根据来源synchronized method
wait()
的基本定义
“当一个线程正在为一个对象执行一个synchronized方法时,所有其他线程都会为同一个对象块调用同步方法(暂停执行),直到第一个线程完成该对象。”
我读到sleeps
它在wait
之前发布锁定。如果lock
释放thread
,那么其他synchronized method
可以进入race condition
并且有意义,因为它可能导致one
?
这是我的示例代码,允许two
和/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Ashish Pancholi
*/
public class Test {
public Test() {
Sharing sharing = new Sharing();
Worker worker_ = new Worker(sharing);
Thread thread_ = new Thread(worker_, "one");
Worker worker = new Worker(sharing);
Thread thread = new Thread(worker, "two");
thread_.start();
thread.start();
}
public static void main(String[] argu) {
Test test = new Test();
}
public class Worker implements Runnable {
private Sharing sharing;
public Worker(Sharing sharing) {
this.sharing = sharing;
}
@Override
public void run() {
sharing.check();
}
}
public class Sharing {
public void check() {
synchronized (this) {
System.out.println("Thread IN " + Thread.currentThread().getName());
try {
wait(5000);
} catch (InterruptedException ex) {
}
System.out.println("Thread OUT " + Thread.currentThread().getName());
}
}
}
}
线程进入synchronized块。
Thread IN one
Thread IN two
Thread OUT one
Thread OUT two
输出 -
{{1}}
答案 0 :(得分:2)
是的,这是有道理的。
wait()
方法的API说:
使当前线程等待,直到另一个线程调用 此对象的
notify()
方法或notifyAll()
方法,或者 指定的时间已过。
因此,如果wait方法 NOT 释放监视器对象上的锁,则没有其他线程可以获取它,因此没有其他线程可以调用notify
或notifyAll
on监控对象。
wait(5000)
表示当前线程在继续之前将等待最多5000毫秒的通知,或者在5000毫秒之后继续。如果要保持锁定并暂停5000毫秒,则必须使用Thread.sleep(5000)
。
答案 1 :(得分:1)
有可能存在竞争条件。在处理多个线程时,竞争条件自然会发生。通过仔细管理线程来阻止它们是你的工作,wait
方法是一个重要的工具,你可以用来帮助它。
通常你不会像这样简单地用5秒的固定时间来呼叫wait
。在实际应用程序中,您可能正在等待某些特定条件成立,因此您的等待看起来更像是这样:
try {
while(!condition) {
wait();
}
doSomething();
} catch(InterruptedException e) {
doSomethingElseWhenWeAreAskedNotToWait();
}
你是否有竞争条件取决于condition
何时变为真,其他人可能正在等待这种情况,以及每个人在发生时所做的事情。 wait
放弃锁定的原因是让condition
有机会在我们等待时变为真实。
答案 2 :(得分:0)
您正在使用synchronized
两个不同的锁,因此两个线程之间不会发生同步。
在Test
而非Sharing
的实例上进行同步,行为将完全不同。