java 多线程同步块不工作
java multithreading synchronized block not working
我不明白为什么我在以下代码中出现异常:class 级别锁定以及对象级别锁定:
似乎对象级锁定应该在这里工作,因为我们正在使用不同的线程更改和访问 hm(Object) 值,但我们仍然得到 exception(java.util.ConcurrentModificationException).
我尝试在代码中注释所有三个锁定。
我知道使用 Hashtable 或 ConcurrentHashMap 我们可以解决这个问题,但是 我想知道使用 HashMap 缺少的概念.
import java.util.HashMap;
class A{
StringBuilder str = new StringBuilder("ABCD");
StringBuilder exception = new StringBuilder("");
HashMap hm = new HashMap();
public void change() {
//synchronized(A.class) {
//synchronized (this){
synchronized (hm){
(this.str).append(Thread.currentThread().getName().toString());
System.out.println(Thread.currentThread().getName()+"::::::"+str);
hm.put(Thread.currentThread(), Thread.currentThread());
}
}
public void impact() {
//synchronized(A.class) {
//synchronized(this) {
synchronized(hm) {
System.out.println(Thread.currentThread()+"...Inside impact :::"+hm.get(Thread.currentThread()));
}
}
public void print() {
System.out.println("Inside print :::"+str);
System.out.println("Inside print :::exception--"+exception);
}
}
class B extends Thread{
A a;
B(A a){
this.a=a;
}
public void run() {
try {
System.out.println("Inside B run::"+a.hm);
a.change();
a.impact();
}
catch(Exception e){
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
System.out.println(sw.toString());
a.exception.append(sw.toString());
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
class C extends Thread{
A a;
C(A a){
this.a=a;
}
public void run() {
try {
System.out.println("Inside C run::"+a.hm);
a.change();
a.impact();
}
catch(Exception e){
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
System.out.println(sw.toString());
a.exception.append(sw.toString());
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
public class multiTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
A a = new A();
for(int i=0;i<=100;i++) {
B b = new B(a);
C c = new C(a);
b.start();
c.start();
}
try {
Thread.currentThread().sleep(5000);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
a.print();
}
}
问题出在这一行:
System.out.println("Inside B run::"+a.hm);
这里有偷偷摸摸的隐式调用 a.hm.toString()
,这会偷偷摸摸地迭代地图的条目;但是你没有同步任何东西,所以你没有对 hashmap 的独占访问权。
放在同步块中:
synchronized (a.hm) {
System.out.println("Inside B run::"+a.hm);
}
(并使 hm
最终化;并且不使用原始类型)。
我不明白为什么我在以下代码中出现异常:class 级别锁定以及对象级别锁定:
似乎对象级锁定应该在这里工作,因为我们正在使用不同的线程更改和访问 hm(Object) 值,但我们仍然得到 exception(java.util.ConcurrentModificationException). 我尝试在代码中注释所有三个锁定。 我知道使用 Hashtable 或 ConcurrentHashMap 我们可以解决这个问题,但是 我想知道使用 HashMap 缺少的概念.import java.util.HashMap;
class A{
StringBuilder str = new StringBuilder("ABCD");
StringBuilder exception = new StringBuilder("");
HashMap hm = new HashMap();
public void change() {
//synchronized(A.class) {
//synchronized (this){
synchronized (hm){
(this.str).append(Thread.currentThread().getName().toString());
System.out.println(Thread.currentThread().getName()+"::::::"+str);
hm.put(Thread.currentThread(), Thread.currentThread());
}
}
public void impact() {
//synchronized(A.class) {
//synchronized(this) {
synchronized(hm) {
System.out.println(Thread.currentThread()+"...Inside impact :::"+hm.get(Thread.currentThread()));
}
}
public void print() {
System.out.println("Inside print :::"+str);
System.out.println("Inside print :::exception--"+exception);
}
}
class B extends Thread{
A a;
B(A a){
this.a=a;
}
public void run() {
try {
System.out.println("Inside B run::"+a.hm);
a.change();
a.impact();
}
catch(Exception e){
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
System.out.println(sw.toString());
a.exception.append(sw.toString());
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
class C extends Thread{
A a;
C(A a){
this.a=a;
}
public void run() {
try {
System.out.println("Inside C run::"+a.hm);
a.change();
a.impact();
}
catch(Exception e){
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
System.out.println(sw.toString());
a.exception.append(sw.toString());
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
public class multiTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
A a = new A();
for(int i=0;i<=100;i++) {
B b = new B(a);
C c = new C(a);
b.start();
c.start();
}
try {
Thread.currentThread().sleep(5000);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
a.print();
}
}
问题出在这一行:
System.out.println("Inside B run::"+a.hm);
这里有偷偷摸摸的隐式调用 a.hm.toString()
,这会偷偷摸摸地迭代地图的条目;但是你没有同步任何东西,所以你没有对 hashmap 的独占访问权。
放在同步块中:
synchronized (a.hm) {
System.out.println("Inside B run::"+a.hm);
}
(并使 hm
最终化;并且不使用原始类型)。