一个简单的 wait() 和 notify() 示例 - 不起作用
A simple wait() & notify() example - doesn't work
我尝试编写一个简单的示例来演示远程控制器操作。
正在通过控制台接受输入,并相应地打印一条消息。
两个线程运行无限循环:主线程等待通知,而另一个线程等待控制台输入。
我想知道如何修复它。问题是通知并没有停止等待:换句话说,打印了单词 "before wait",但没有打印单词 "after wait"。顺便说一句,没有 while(true) 循环它工作正常(按下一个按钮)。
非常感谢
public class MainTV {
public static int lastRemoteCode = 0;
public static void main(String[] args){
RemoteControllerThread remote = new RemoteControllerThread();
remote.start();
synchronized(remote){
while(true){
try {
System.out.println("before wait");
remote.wait();
System.out.println("after wait");
switch (lastRemoteCode){ //we use switch because there are many code options
case 0:
System.out.println("Error with remote button reading");
break;
case 3:
System.out.println("Volume Down button was pressed now!");
break;
case 4:
System.out.println("Volume Up button was pressed now!");
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
第二个class(模拟遥控器):
import java.util.Scanner;
public class RemoteControllerThread extends Thread{
public void run(){
synchronized(this){
Scanner in = new Scanner(System.in);
while(true){
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
notify();
System.out.println("after notify");
}
}
}
}
我认为你的代码有两个问题。
当主线程执行到 synchronized(remote)
时,它可能不会继续,因为远程控制器线程(可能)已经锁定了 remote
对象。将 remote.start()
移动到 synchronized(remote)
块中。
为了让执行从wait
继续,您需要在notify
之后释放对象锁。更改线程中的同步块,如:
-
public void run() {
Scanner in = new Scanner(System.in);
while(true){
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
synchronized(this) {
notify();
}
System.out.println("after notify");
}
}
两个线程在同一个对象上同步,this
指的是与 remote
相同的对象,并且由于这两个同步块内部都有无限循环,所以这会产生问题。其中一个线程将等待另一个线程完成,但这种情况永远不会发生(因为无限循环)。
要解决此问题,您应该只同步需要同步的代码,例如 wait()
和 notify()
调用。
引用自notify()
JavaDoc:
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object
您的遥控器永远不会松开锁。如果您将 synchronized
切换为 while
,您的机会很小,但通常您远程会立即取回锁定。以下作品为例:
class RemoteControllerThread extends Thread {
public void run() {
while (true) {
synchronized (this) {
Scanner in = new Scanner(System.in);
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
notify();
System.out.println("after notify");
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
我尝试编写一个简单的示例来演示远程控制器操作。 正在通过控制台接受输入,并相应地打印一条消息。
两个线程运行无限循环:主线程等待通知,而另一个线程等待控制台输入。
我想知道如何修复它。问题是通知并没有停止等待:换句话说,打印了单词 "before wait",但没有打印单词 "after wait"。顺便说一句,没有 while(true) 循环它工作正常(按下一个按钮)。
非常感谢
public class MainTV {
public static int lastRemoteCode = 0;
public static void main(String[] args){
RemoteControllerThread remote = new RemoteControllerThread();
remote.start();
synchronized(remote){
while(true){
try {
System.out.println("before wait");
remote.wait();
System.out.println("after wait");
switch (lastRemoteCode){ //we use switch because there are many code options
case 0:
System.out.println("Error with remote button reading");
break;
case 3:
System.out.println("Volume Down button was pressed now!");
break;
case 4:
System.out.println("Volume Up button was pressed now!");
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
第二个class(模拟遥控器):
import java.util.Scanner;
public class RemoteControllerThread extends Thread{
public void run(){
synchronized(this){
Scanner in = new Scanner(System.in);
while(true){
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
notify();
System.out.println("after notify");
}
}
}
}
我认为你的代码有两个问题。
当主线程执行到
synchronized(remote)
时,它可能不会继续,因为远程控制器线程(可能)已经锁定了remote
对象。将remote.start()
移动到synchronized(remote)
块中。为了让执行从
wait
继续,您需要在notify
之后释放对象锁。更改线程中的同步块,如:
-
public void run() {
Scanner in = new Scanner(System.in);
while(true){
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
synchronized(this) {
notify();
}
System.out.println("after notify");
}
}
两个线程在同一个对象上同步,this
指的是与 remote
相同的对象,并且由于这两个同步块内部都有无限循环,所以这会产生问题。其中一个线程将等待另一个线程完成,但这种情况永远不会发生(因为无限循环)。
要解决此问题,您应该只同步需要同步的代码,例如 wait()
和 notify()
调用。
引用自notify()
JavaDoc:
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object
您的遥控器永远不会松开锁。如果您将 synchronized
切换为 while
,您的机会很小,但通常您远程会立即取回锁定。以下作品为例:
class RemoteControllerThread extends Thread {
public void run() {
while (true) {
synchronized (this) {
Scanner in = new Scanner(System.in);
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
notify();
System.out.println("after notify");
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}