Java 两个线程如何同时锁定同一个对象?

Java 两个线程如何同时锁定同一个对象?,java,multithreading,debugging,runnable,synchronized,Java,Multithreading,Debugging,Runnable,Synchronized,我正在写一个多线程程序来打印从1到n的数字 我有两个线程,其中有一个转轮可以打印奇数数字。还有一个线程,它有一个转轮,可以打印偶数数字 while (true) { synchronized (ng) { while (ng.getData() % 2 == 1) { try { ng.wai

我正在写一个多线程程序来打印从1到n的数字

我有两个线程,其中有一个转轮可以打印
奇数
数字。还有一个线程,它有一个转轮,可以打印
偶数
数字

while (true) {              
            synchronized (ng) {                 
                while (ng.getData() % 2 == 1) {
                    try {
                        ng.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                ng.increment();
                ng.notify();
}
我已将调试点放在同步方法中。附加快照:

在名为
notify()
的第一个线程之后,在调试选项卡中,它仍然显示

拥有NumberGenerator

您可以在快照中看到:

它说有两个线程:线程1和线程2拥有NumberGenerator对象。


两个线程如何同时持有对象上的锁

两个线程不可能同时持有同一个锁。这可能是由于两个线程在调试器中显示的数据之间交换了锁定。例如,调试器将获取线程1的数据,然后线程1释放锁,然后由线程2获取锁,调试器将获取线程2的数据。这将使两个线程似乎同时拥有锁。这个问题的答案很好地解释了这一点:


但是我同意Elliot的观点,如果你只想把数字1打印成n,那么for循环就是最好的选择。但是,如果您想了解线程如何工作,拥有两个线程可能是一个很好的练习

两个线程不可能同时持有同一个锁。这可能是由于两个线程在调试器中显示的数据之间交换了锁定。例如,调试器将获取线程1的数据,然后线程1释放锁,然后由线程2获取锁,调试器将获取线程2的数据。这将使两个线程似乎同时拥有锁。这个问题的答案很好地解释了这一点:


但是我同意Elliot的观点,如果你只想把数字1打印成n,那么for循环就是最好的选择。但是,如果您想了解线程的工作原理,使用两个线程可能是一个很好的练习

如果您想按顺序打印数字1到n,请不要使用多个线程!您的意思是我应该使用
for loop
,对吗?或者您可以使用并行流:)我的意思是,这正是顺序任务的定义,使并行应用程序按顺序运行没有好处,而且运行并行作业也有成本。这是Amdahl定律的直接结果。不太熟悉这一点,因为有这么多好的库保护我们不必自己编写这种代码,但是。。你不是应该从
同步的
块内部
notify()
吗?我能找到的所有示例都使用该模式,但是在
synchronized
块之外有
notify()
。这会导致问题吗?如果要按顺序打印数字1到n,请不要使用多个线程!您的意思是我应该使用
for loop
,对吗?或者您可以使用并行流:)我的意思是,这正是顺序任务的定义,使并行应用程序按顺序运行没有好处,而且运行并行作业也有成本。这是Amdahl定律的直接结果。不太熟悉这一点,因为有这么多好的库保护我们不必自己编写这种代码,但是。。你不是应该从
同步的
块内部
notify()
吗?我能找到的所有示例都使用该模式,但是在
synchronized
块之外有
notify()
。这可能是问题的原因吗?这看起来像是学习
synchronized
notify()
wait()
的练习。用正确的方法做可能不如用教育性的方法做重要:)这看起来像是学习
synchronized
notify()
wait()
的练习。用正确的方式做可能不如用教育的方式做重要:)