gpt4 book ai didi

不同方法中同一对象上的Java同步块(synchronized block)

转载 作者:行者123 更新时间:2023-11-29 09:28:36 24 4
gpt4 key购买 nike

我想了解 java 中同步块(synchronized block)的概念。根据我阅读的文件,我了解到如果我们获得一个锁(使用实例变量的同步块(synchronized block))然后我们无法在该类中的同一对象上获取同步锁。但当我实际尝试使用以下代码片段时,我发现我的理解出错了。

即我能够获得锁(同一实例变量上的同步块(synchronized block))在两个不同的同时方法。当线程启动时,它将运行方法并无限期地等待并且不会从同步中出来堵塞。同时,如果我使用相同的方法调用停止方法线程它进入同步块(synchronized block)并执行通知陈述。我在 Java 文档中进行了搜索,但找不到任何内容。

这是代码片段:

public class MyClass extends Thread
{
private Object lock = new Object();
public void run()
{
synchronized(lock)
{
lock.wait()
}
//other code
}
public void stop()
{
synchronized(lock)
{
lock.notify()
}
//other code
}
}

这是我如何管理 MyClass 线程的代码片段:

public class MyClassAdmin 
{
MyClass _myclass;
public MyClassAdmin()
{
_myclass=new MyClass();
_myclass.start();
}
public void stop()
{
_myclass.stop();
}
public static void main(String args[])
{
MyClassAdmin _myclassAdmin=new MyClassAdmin();
_myclassAdmin.stop();
}
}

根据我的理解,当线程启动时,它将获取“lock”对象上的锁(MyClass 的 run 方法中的同步块(synchronized block))。当我调用停止方法时,它应该无限期地等待,直到运行方法从同步块(synchronized block)中出来(在这种情况下永远不会发生)。但是当我执行时,调用 stop 方法获取了“锁”对象上的锁并通知了导致线程关闭的对象。

最佳答案

您的两种方法都使用相同的锁。如果您的 MyClass 线程碰巧在主线程可以调用停止方法之前开始等待,您的停止方法仍然可以继续,因为等待线程释放了锁。一旦线程进入 wait 方法,它就会在进入 hibernate 状态之前释放锁,并且在退出 wait 方法之前不会重新获取锁。

这是相关的API doc for Object#wait ,第二段涵盖了我上面描述的关于 wait 如何释放锁的内容。注意它说你必须在循环中调用这个方法的部分,否则你有一个顺序依赖错误,当通知到达主线程之前其他线程可以开始等待时,它会导致等待线程挂起。

public final void wait() throws InterruptedException

Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).

The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:

 synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}

This method should only be called by a thread that is the owner of this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.

了解这是一个玩具示例,但是子类化 Thread 和重写 Thread 方法令人困惑。使用 Runnable 而不是 Thread 的原因之一是没有机会通过错误地覆盖 Thread 方法而导致问题。

关于不同方法中同一对象上的Java同步块(synchronized block),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35745160/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com