我正在努力学习使用wait并通知。
我需要一个应用程序,每10秒向用户询问线程是否必须继续工作。 如果不是(用户按下n),则线程必须等到用户在控制台上写“y”。
我必须使用等待和通知,但我不知道如何。
我正在尝试在没有用户提示的情况下实现wait和notify。
这是创建两个线程的主类,FolderThread是必须工作的线程,而ControlThread是必须向用户询问是否要继续的人。
public class MainClass {
public static void main(String[] args) throws InterruptedException {
FolderThread folder = new FolderThread();
Thread t = new Thread(folder);
ControlThread control = new ControlThread(folder);
Thread t2 = new Thread(control);
t.start();
t2.start();
}
}
FolderThread
public class FolderThread implements Runnable {
@Override
public void run() {
while(true) {
System.out.println("started");
synchronized(this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
ControlThread
public class ControlThread implements Runnable {
FolderThread folder;
public ControlThread (FolderThread folder) {
this.folder = folder;
}
@Override
public void run() {
synchronized(folder) {
folder.notify();
}
}
}
问题是它打印“已启动”然后等待永远不会发出的通知!为什么呢?
答案 0 :(得分:1)
这里发生的事情是你的notify
正在运作,但它不会做任何其他事情而不只是"醒来"另一个线程,直到它回到等待,然后控制线程完成,所以它永远不会醒来"第二个线程。
基本上,如果您不想编写用户输入部分,可以使用
进行模拟Thread.sleep(2000);
// and then do what would be done if the user had type 'y'
在这种情况下,剩下的问题是当你通知你的其他线程时,没有任何事情可以完成。所以你需要两件事:
所以你应该做的修改:
在main方法中创建一个AtomicBoolean:
AtomicBoolean flag = new AtomicBoolean();
将AtomicBoolean传递给两个线程的构造函数:
FolderThread folder = new FolderThread(flag);
ControlThread control = new ControlThread(folder, flag);
当然,您需要调整构造函数声明。
获取FolderThread以在醒来时检查标志。将while(true)
替换为
while(flag.get() == false)
获取ControlThread以在想要停止时更新标志:
flag.set( true );
值得注意的是,为了实现简单的工人 - 控制器关系,其中通信仅限于停止工作线程,您不需要wait
和notify
。您可以让控制器线程使用t.interrupt()
答案 1 :(得分:0)
这是我的解决方案(来自用户的输入)
FolderThread
public class FolderThread implements Runnable {
@Override
public void run() {
while(true) {
System.out.println("Checking...");
synchronized(this) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
ControlThread
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ControlThread implements Runnable {
FolderThread folder;
public ControlThread (FolderThread folder) {
this.folder = folder;
}
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true) {
InputStreamReader is = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(is);
try {
do {
System.out.println("Continue? y/n");
}
while(br.readLine().equals("n"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(folder) {
folder.notify();
}
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}