请考虑以下代码: -
public class UsingWait1{
public static void main(String... aaa){
CalculateSeries r = new CalculateSeries();
Thread t = new Thread(r);
t.start();
synchronized(r){
try{
r.wait(); //Here I am waiting on an object which is Runnable. So from its run method, it can notify me (from inside a synchronized block).
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
System.out.println(r.total);
try{
Thread.sleep(1);
} catch (InterruptedException e){
System.out.println("Interrupted");
}
System.out.println(r.total);
}
}
class CalculateSeries implements Runnable{
int total;
public void run(){
synchronized(this){
for(int i = 1; i <= 10000; i++){
total += i;
}
notify(); // Line 1 .. Notify Exactly one of all the threads waiting on this instance of the class to wake up
}
}
}
这里我正在等待Runlate的CalculateSeries。所以我可以通过CalculateSeries的run()方法通知等待线程。
但是现在,请考虑以下代码,我在等待一个不是Runnable的对象。
public class WaitNotOnThread{
public static void main(String... aaa){
NotRunnable nr = new NotRunnable();
IAmRunnable r = new IAmRunnable(nr);
new Thread(r).start();
synchronized(nr){
try{
nr.wait();
} catch(InterruptedException e){
System.out.println("Wait interrupted");
}
System.out.println("After being notified within synchronized");
}
System.out.println("After synchronized");
}
}
class IAmRunnable implements Runnable{
NotRunnable nr;
IAmRunnable(NotRunnable nr){
this.nr = nr;
}
public void run(){
synchronized(nr){
try{
Thread.sleep(1000);
} catch(InterruptedException e){
System.out.println("Sleeping Interrupted :( ");
}
notify(); // Line 2
}
}
}
class NotRunnable{
}
这里我在第2行得到一个IllegalMonitorStateException。我在调用对象的同一个实例(不是Runnable)时等待,同时调用wait()和notify()。那问题是什么?
有人也可以提供一些场景,等待一个不是Runnable的对象会有用吗?
答案 0 :(得分:4)
等待不必在Runnable上。这就是为什么notify()在Object而不在Runnable上。我想在所有情况下我们都希望避免忙碌等待。
问题似乎是synchronized()在nr上,并且在不同的对象上调用notify。同步应该是最终变量。
class IAmRunnable implements Runnable {
final NotRunnable nr;
IAmRunnable( final NotRunnable nr) {
this.nr = nr;
}
public void run() {
synchronized (nr) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Sleeping Interrupted :( ");
}
nr.notify(); // Line 2
}
}
}