使用同步,我基本上有两个执行相同对象的方法的cuncurrent线程,但可能我遇到了错误。
鉴于这段代码
public class Test {
public static void main(String... args) throws InterruptedException{
new Test();
}
Test() throws InterruptedException{
Stuff s = new Stuff();
Th t1 = new Th(1,s);
Th t2 = new Th(2,s);
t1.start();
Thread.sleep(1000);
t2.start();
}
}
class Stuff{
public Integer count=0;
void doStuff(int threadId){
System.out.println(threadId + ": in doStuff");
synchronized (count) {
count += 100;
if (threadId == 1) {
try {Thread.sleep(3000);}
catch (InterruptedException e) {e.printStackTrace();}
}
System.out.println(threadId + ": count = " + count);
}
}
}
class Th extends Thread{
public Stuff s;
public int id;
@Override
public void run(){
System.out.println(id+": thread run");
s.doStuff(id);
}
Th(int id_,Stuff s_){
s=s_;
id=id_;
System.out.println(id+": thread created");
}
}
我得到了这个输出
1: thread created 2: thread created 1: thread run 1: in doStuff 2: thread run 2: in doStuff 2: count = 200 1: count = 200
为什么t1
打印“200”?
t2
不能等t1
执行同步块,然后才能锁定count
,然后执行阻止?
答案 0 :(得分:10)
synchronized (count) {
count += 100;
这不起作用。
您正在同步对象,而不是变量或字段。
每次增加count
时,该字段都会指向不同的Integer
对象。因此,您的同步块始终使用不同的监视器。
你需要找到一个稳定的"锁定对象,例如
private final Object lockMonitor = new Object();
(然后你可以说synchronized (lockMonitor){}
代替)