为什么这个同步语句示例不起作用?

时间:2015-04-20 04:10:52

标签: java multithreading

使用同步,我基本上有两个执行相同对象的方法的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,然后执行阻止?

1 个答案:

答案 0 :(得分:10)

 synchronized (count) {
        count += 100;

这不起作用。

您正在同步对象,而不是变量或字段。

每次增加count时,该字段都会指向不同的Integer对象。因此,您的同步块始终使用不同的监视器。

你需要找到一个稳定的"锁定对象,例如

 private final Object lockMonitor = new Object();

(然后你可以说synchronized (lockMonitor){}代替)