1)一旦在该线程同步代码块中调用notify,或者退出同步代码块,线程是否放弃它的锁定?
例如,似乎没有指定线程优先级,我的Process类将从上到下执行。首先调用Produce,然后调用stuff,然后wait();消耗将运行,然后它命中notify(),这将打印“完成”或首先会有5秒的延迟,然后“完成”将被打印?
2)另外,如果我有第三个同步的方法/线程,它不等待或通知并且只是运行,我可以预测我的操作先验执行的顺序吗?
3)最后,notify()如何知道'唤醒'的线程?比如,假设我有多个进程,每个进程同时执行2个线程,每个进程A,B和C都会激活notify()。每个进程的每个notify()都是本地的吗?换句话说,如果进程A调用notify(),是否可以唤醒进程B中的等待线程?到目前为止,我已经看到了synchronized this(this),这让我觉得它引用了一个特定的对象类,这反过来让我觉得在synchronized块中调用的所有notify()都被同步中的任何一个绑定(这是指,所以没有交叉。
public class Process {
public void produce( ) {
synchronized(this) {
// do stuff
wait( );
System.out.println("Done");
}
}
public void consume( ) {
synchronized(this) {
// stuff
notify();
Thread.sleep(5000);
}
}
}
答案 0 :(得分:3)
你可以写一个简单的程序来测试这个
public static void main(String[] args) throws Exception {
final Process e = new Process();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
e.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
e.produce();
}
该程序等待5000毫秒并打印
Done
关于你的问题
1)一旦调用notify,线程是否放弃它的锁定 在那个线程内同步代码块,或者一旦同步 退出代码块?
notify()
个州的javadoc
如果有任何线程在等待这个对象,选择其中一个 被唤醒选择是任意的,由酌情决定 实现。**强文线程通过调用等待对象的监视器 其中一种等待方法。
唤醒的线程将无法继续直到当前 线程放弃对此对象的锁定
所以,不,在调用notify()
时,线程不会放弃对锁的控制。当代码退出synchronized
块时,就会发生这种情况。
2)另外,如果我有第三个同步方法/线程,那不会 等待或通知,只是运行,我可以预测我的顺序 操作先验执行?
你可以估计,但你不能确定。执行由Thread调度程序决定。
3)最后,notify()如何知道'唤醒'的线程?
电话不知道。 Thread调度程序知道并选择。你无法控制它。
wait()
和notify()
州
此方法只应由作为其所有者的线程调用 这个对象的监视器。
和
IllegalMonitorStateException - 如果当前线程不是所有者 该对象的监视器。
因此,当您在同一个对象上的synchronized
块内时,您只能在对象上调用它们。
在您的代码示例中,调用
wait();
隐含地做
this.wait();
答案 1 :(得分:2)
一旦在该线程同步代码块中调用notify,或者退出同步代码块,线程是否放弃它的锁定?
当'synchronized'块退出时。 notify()
本身并不影响锁定。
首先会有5秒的延迟,然后会打印“完成”吗?
是
另外,如果我有第三个同步方法/线程,它不等待或通知并且只是运行,我可以预测我的操作先验执行的顺序吗?
您无法使用线程预测任何内容。如果您想要特定的执行订单,则不会使用它们。
最后,notify()如何知道'唤醒'的线程?
没有。它'唤醒正在等待此对象监视器的单个线程。如果任何线程正在等待此对象,则选择其中一个线程被唤醒。选择是任意的,由实施决定。
就像我们说的那样,我有多个进程同时执行2个线程,每个进程A,B和C都会激活notify()。每个进程的每个notify()都是本地的吗?
notify()
与您的课程无关。它会通知对象并唤醒线程。
换句话说,如果进程A调用notify(),是否可以唤醒进程B中的等待线程?
是
到目前为止,我已经看过synchronized called(this),这让我认为它指的是一个特定的对象类
没有。它指的是特定的对象。
反过来让我认为同步块中调用的所有notify()都被synchronized(this)所引用的内容绑定,因此不存在交叉。
不要这么想。你过度思考了这一点。 synchronized(x)
在对象x
上进行同步,x.notify()
通知它。周期。