根据来自synchronized method
的link的基本定义
“当一个线程正在为一个对象执行一个synchronized方法时,所有其他线程都会为同一个对象块调用同步方法(暂停执行),直到第一个线程完成该对象为止。”
我读到有关wait()
的信息,它在sleeps
之前释放锁定。如果wait
释放lock
然后其他thread
可以进入synchronized method
并且它有意义,因为它可能导致race condition
,这里有一个混乱?
这是我的示例代码,允许one
和two
线程进入synchronized块。
/*
* 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());
}
}
}
}
输出 -
Thread IN one
Thread IN two
Thread OUT one
Thread OUT two
有可能存在竞争条件。在处理多个线程时,竞争条件自然会发生。通过仔细管理线程来阻止它们是你的工作,而wait
方法是一个重要的工具,你可以用来帮助它。
通常情况下,你不会简单地用wait
调用固定的5秒钟。在实际应用程序中,您可能正在等待某些特定条件成立,因此您的等待看起来更像是:
try {
while(!condition) {
wait();
}
doSomething();
} catch(InterruptedException e) {
doSomethingElseWhenWeAreAskedNotToWait();
}
你是否有竞争条件取决于condition
何时成为真实,还有谁可能在等待这种情况,以及每个人在发生时所做的事情。 wait
放弃锁定的原因是让condition
有机会在我们等待时变为真实。
是的,这是有道理的。
wait()
方法的API说:
导致当前线程等待,直到另一个线程调用此对象的
notify()
方法或notifyAll()
方法,或者已经过了指定的时间量。
因此,如果wait方法不会释放监视器对象上的锁,则没有其他线程可以获取它,因此没有其他线程可以在该监视器对象上调用notify
或notifyAll
。
wait(5000)
表示当前线程在继续之前将等待最多5000毫秒的通知,或者在5000毫秒之后继续。如果你想保持锁定并暂停5000毫秒,那么你必须使用Thread.sleep(5000)
。
您正在使用带有两个不同锁的synchronized
,因此两个线程之间不会发生同步。
在Test
而不是Sharing
的实例上同步,行为将完全不同。