java和同步

时间:2012-09-22 12:39:18

标签: java synchronization

我正在准备SCJP考试,我在完全理解同步方面遇到了麻烦。在第6行,我已经读过在main中运行的线程需要锁定'b'。为什么需要锁定此对象?我的理解是同步的代码块是一个受保护的区域,任何时候只有一个线程可以进入?继续,main中的线程释放此锁并等待'b中的线程完成其run方法。然后'b'中的线程用于通知main中的线程已完成。但是,它看起来并不像是通知任何特定的线程。这个例子来自Sierra和Bates SCJP的书。任何可以在这上面散发的光都会受到赞赏。感谢

class ThreadA {  
    public static void main(String [] args) {  
        ThreadB b = new ThreadB();  
        b.start();  

        **synchronized(b) {  //line 6**
            try {  
                System.out.println("Waiting for b to complete...");  
                b.wait();  
            } catch (InterruptedException e) {}  
                System.out.println("Total is: " + b.total);  
            }  
        }  
    }  
}

class ThreadB extends Thread {     
    int total;  

    public void run() {  
        System.out.println("K");  
        synchronized(this) {  
            for(int i=0;i<100;i++) {  
                total += i;  
            }  
            notify();  
        }  
    }  
}

4 个答案:

答案 0 :(得分:2)

这两个线程在这里Object同步,即bmain()首先获取锁定,然后调用b.wait(),这会释放锁定并等待某人在notify()上呼叫b

这意味着当run()方法(在本案例中调用b时)调用notify()时,这将再次唤醒main()方法。

因此,b上获取的锁在这里并不重要,重要的是两个线程都获取相同的锁,否则wait()/notify()合作将无效。

答案 1 :(得分:2)

  

在第6行,我已经读过在main中运行的线程需要锁定'b'。为什么需要锁定此对象?

因为这就是那条线的作用。它获得了该资源。其他线程可以获得其他同步块,但没有其他线程可以获取该对象的锁定。

  

它看起来不像是通知任何特定的线程。

这是事实。程序不知道哪个线程将被通知,或者即使任何线程将被通知。您作为开发人员可能会得出结论,有一个特定的线程将被通知,也许是因为它是唯一的线程wait()ing。

答案 2 :(得分:2)

这是一个非常极端的案例,你会这样做 会发生什么是main线程在ThreadB对象和wait上同步 当ThreadB完成后,会引发notify,结果main被唤醒并继续。
但这不是您通常编写的代码,即Thread使用synchronization个对象 要查看此案例如何,只需从notify的循环中删除ThreadB 由于您在Thread对象上进行同步,并且实现在Thread完成后引发通知,因此代码仍然有效。 这种行为是违反直觉的,容易出错。

答案 3 :(得分:0)

代码使用wait()机制来确保result由其他ThreadB计算。

要等待对象,您需要获取line 6synchronized (b)进入图片的对象的锁定。

执行相同程序的更好方法是使用Thread#join()方法。

public final void join()
            throws InterruptedException

Waits for this thread to die.