繁体   English   中英

Java和同步

[英]java and synchronization

我正在为SCJP考试做准备,但是在完全了解同步方面遇到了麻烦。 在第6行,我读到main中运行的线程需要锁定'b'。 为什么需要对此对象进行锁定? 我的理解是,同步的代码块是一个受保护的区域,任何时间只能有一个线程进入? 继续前进,main中的线程释放此锁定,并等待'b中的线程完成其run方法。 然后,“ b”中的线程将通知main中的线程已完成。 但是,它看起来并不像在这里通知任何特定线程。 此示例来自Sierra and 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();  
        }  
    }  
}

这两个线程在同一个Object上同步,即b main()首先获取锁,然后调用b.wait() ,后者释放锁并等待有人在b上调用notify()

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

因此,在b上获得锁并不真正重要,重要的是两个线程都获得相同的锁,否则wait()/notify()合作将无法正常进行。

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

因为那是那条线所做的。 它获取该资源。 其他线程可以获取其他同步块,但是没有其他线程可以获取该对象的锁。

它似乎没有在这里通知任何特定的线程。

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

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

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

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

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

public final void join()
            throws InterruptedException

Waits for this thread to die.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM