java中synchronized(expr){}中expr的意义

时间:2012-11-18 09:15:42

标签: java multithreading synchronization

根据我的理解,我们在java中使用“synchronized statement”来阻止多个线程之间的干扰。

现在我试图在下面的表达中理解expr的重要性。

synchronized(expr){     声明 }

因为看起来像锁定行为取决于expr对象。

e.g。

public class Sync extends Thread {
    static int [] arr = {0,1,2};
    Object lock = new Object();
    public static void main(String[] args){

        Sync ob1 = new Sync();
        Sync ob2 = new Sync();
        ob1.start();
        ob2.start();

    }
    @Override
    public void run() {
        synchronized (arr) {
            for(int i = 0;i < arr.length; ++i){
                try {

                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " "  + arr[i]);

            }
        }

    }
}

现在在上面的示例中,当我在synchronized语句中使用“arr”对象(synchronized(arr))时,我得到了一致的预期输出,如下所示。
线程-0 0
线程-0 1
线程-0 2
线程-1 0 螺纹-1 1 螺纹-1 2

但是当我在synchronized语句中使用“lock”对象(synchronized(lock))时,我得到如下输出。

线程-0 0
线程-1 0 线程-0 1
螺纹-1 1 线程-0 2
线程-1 2

两种情况下输出都不应相同。

谢谢,
山塔努

1 个答案:

答案 0 :(得分:3)

arr Object本质上是静态的,因此两个线程共享相同的arr,如果lock为instance object,它将在两个线程中有两个不同的实例。

因此,当你在这里与arr对象进行同步时,任何首先进入阻塞arr object的块并且将完成其执行的线程将会等到第一个线程完成或释放锁。

在锁定对象的情况下,它完成两个不同的对象(两个资源),因此每个线程持有不同资源或对象的锁,因此执行将是并行的。