抱歉我的格式不正确。我正在使用记事本来编写我的程序。
这是一个有效的代码。我唯一的问题是,我已经读过必须在Synchornized块中使用notify和wait。但是,在以下示例中,wait和notify未在同步块中使用,仍然不会引发错误。
class counthrd implements Runnable {
Thread thrd;
String x;
counthrd cnt1;
counthrd() {
}
boolean suspended;
boolean stopped;
counthrd(String s, counthrd cnt1) {
thrd = new Thread(this, s);
this.cnt1 = cnt1;
thrd.start();
x = s;
}
public void run() {
try {
System.out.println("Starting " + thrd.currentThread().getName());
for (int i = 1; i < 100; i++) {
System.out.print(i + " ");
if ((i % 10) == 0) {
System.out.println();
Thread.sleep(500);
}
//synchronized(cnt1){
while (suspended) {
System.out.println("going to wait mode");
wait();
notify();
}
//}
}
} catch (Exception e) {
System.out.println(e);
}
}
synchronized void suspendme() {
suspended = true;
notify();
}
synchronized void resumeme() {
suspended = false;
notify();
}
}
class counter {
public static void main(String args[]) throws InterruptedException {
counthrd cnt1 = new counthrd();
counthrd cnthrd1 = new counthrd("thrd 1", cnt1);
Thread.sleep(1000);
System.out.println("going to wait mode");
cnt1.suspendme();
Thread.sleep(1000);
System.out.println("resuming");
cnt1.resumeme();
Thread.sleep(1000);
}
}
答案 0 :(得分:3)
见my comment。由于永远不会抛出IllegalMonitorStateException
,因此我们知道永远不会调用wait
。
请注意,您有两个counthrd
...
counthrd cnt1 = new counthrd();
counthrd cnthrd1 = new counthrd("thrd 1", cnt1);
查看您正在呼叫suspendme
和resumeme
的实例?
Thread.sleep(1000);
System.out.println("going to wait mode");
cnt1.suspendme();
Thread.sleep(1000);
System.out.println("resuming");
cnt1.resumeme();
Thread.sleep(1000);
使用你的no-arg构造函数初始化 cnt1
,如下所示:
counthrd() {
}
关键是cnt1
实际上从未开始自己的线程。它真的没有做任何事情。 cnthrd1
是启动线程的那个,如下所示:
counthrd(String s, counthrd cnt1) {
thrd = new Thread(this, s);
this.cnt1 = cnt1;
thrd.start();
x = s;
}
要点是suspended
是一个实例字段,而不是在cnt1
和cnthrd1
之间共享。修改cnt1.suspended
不会导致cnthrd1
进入“等待模式”。永远不会调用wait
,因此永远不会抛出异常。
要演示,请尝试在suspendme
上调用resumeme
和cnthrd1
,而不是......: - )
C:\dev\scrap>javac counter.java
C:\dev\scrap>java counter
Starting thrd 1
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
going to wait mode
going to wait mode
java.lang.IllegalMonitorStateException
resuming
话虽这么说,我想我建议你做一些你的代码应该做的事情。
suspended
声明为volatile
。如果没有一些明确的内存排序保证,则无法保证何时甚至如果 cnthrd1
读取suspended
的更新值。cnt1
字段和实例;他们没有理由。摆脱那个空构造函数。Thread.currentThread
是一种静态方法;你不需要使用它的实例。除此之外,thrd
保证等于Thread.currentThread
。counthrd.x
等于thrd.getName
;为什么不直接使用x
?x
而不是name
?而不是thrd
,为什么不thread
?而不是counthrd
,为什么不CountingThread
?notify
中的resumeme
,而不是suspendme
。 (事实上,如果线程处于休眠状态,即notify
)suspendme
中的InterruptedException
可能会意外触发(i % 10) == 0
notify
循环中有while (suspended)
。您的while
循环现在也可以变为if
语句。synchronized (this)
围绕调用while
。thrd.start()
。 suspend
不一定是synchronized
。 resume
也不一定是synchronized
;只有wait
和notify
来电需要它。您可以找到正常运行的示例的修改版here。