如何从单独的线程暂停主线程?
How can I pause Main thread from a separate thread?
我正在开发一个应用程序,需要能够在处理过程中暂停主线程。我的想法是拥有三个线程:主线程,一个监听输入(STOP 或 GO 命令)的线程,然后另一个线程使主线程停止:
public static boolean stopped = false;
public static void main (String[] args){
Thread main = Thread.currentThread();
Runnable t1 = new Runnable() {
public void run() {
while(true){
Scanner s = new Scanner(System.in);
// wait for command
String in = s.nextLine();
if(in.equals("STOP")){
synchronized(main){
stopped = true;
//create new thread to make main wait
Runnable t2 = new Runnable() {
public void run(){
synchronized(main){
while(stopped){
main.wait();
}
}
}
};
Thread th2 = new Thread(t2);
th2.start();
}
}
if (in.equals("GO")){
synchronized(main){
stopped = false;
main.notifyAll();
}
}
}
}
};
Thread th1 = new Thread(t1);
th1.start();
while(true){
synchronized(main){
// Do lots of stuff that needs to pause when user enters STOP
System.out.println("Main is running");
Thread.sleep(5000);
}
}
}
}
即使在发出 STOP 命令后,目前 main 仍在继续其循环。有没有办法锁定 main 直到另一个线程释放它而不必在 main 中执行 wait()
?
您不想按照自己的方式构建它。您不希望线程在任意点停止;尝试恢复时可能会导致问题。相反,给线程明确的停止点。
例如,您可以创建一个工作线程,让程序的主线程管理命令并将指令委托给您的工作线程。 process
方法是一种 增量 工作量,例如读取大文件的一行。例如,假设这是您的辅助任务:
public abstract class Worker implements Runnable {
private final Object lock = new Object();
private final AtomicBoolean shouldWait = new AtomicBoolean();
protected abstract boolean processingIsComplete();
protected abstract void process();
protected abstract void cleanUpResources();
public Object getLock() {
return lock;
}
public void disable() {
shouldWait.set(false);
}
public void enable() {
shouldWait.set(true);
}
@Override
public void run() {
try {
while(!processingIsComplete()) {
while(!shouldWait.get()) {
synchronized(lock);
lock.wait();
}
}
process();
}
} catch(InterruptedException e) {
System.out.println("Worker thread stopped");
} finally {
cleanUpResources();
}
}
}
然后,修改/subclass worker 来真正做处理工作。然后,在您的主 class 中,您可以根据需要打开和关闭您的工作人员。这只是一个骨架,显然您可以将行为重构为多个方法,添加其他控件,例如读取工作线程的状态等:
public static void main (String[] args) throws Exception {
Worker worker = new WorkerImpl(/* whatever args are needed */);
Thread workerThread = new Thread(worker);
System.out.println("Starting process...");
worker.start();
Scanner sc = new Scanner(System.in);
while(true) {
System.out.printn("Please enter command: ");
String command = sc.nextLine();
if("END".equals(command)) {
System.out.println("Terminating program... ");
workerThread.interrupt();
break;
} else if ("GO".equals(command)) {
synchronized(worker.getLock()) {
System.out.println("Continuing worker thread... ");
worker.enable();
worker.getLock().notifyAll();
}
} else if ("STOP".equals(command)) {
synchronized(worker.getLock()) {
System.out.println("Stopping worker thread ");
worker.disable();
worker.getLock().notifyAll();
}
} else {
printCommandHelp();
}
}
};
进一步阅读:How to use wait and notify in Java?
我正在开发一个应用程序,需要能够在处理过程中暂停主线程。我的想法是拥有三个线程:主线程,一个监听输入(STOP 或 GO 命令)的线程,然后另一个线程使主线程停止:
public static boolean stopped = false;
public static void main (String[] args){
Thread main = Thread.currentThread();
Runnable t1 = new Runnable() {
public void run() {
while(true){
Scanner s = new Scanner(System.in);
// wait for command
String in = s.nextLine();
if(in.equals("STOP")){
synchronized(main){
stopped = true;
//create new thread to make main wait
Runnable t2 = new Runnable() {
public void run(){
synchronized(main){
while(stopped){
main.wait();
}
}
}
};
Thread th2 = new Thread(t2);
th2.start();
}
}
if (in.equals("GO")){
synchronized(main){
stopped = false;
main.notifyAll();
}
}
}
}
};
Thread th1 = new Thread(t1);
th1.start();
while(true){
synchronized(main){
// Do lots of stuff that needs to pause when user enters STOP
System.out.println("Main is running");
Thread.sleep(5000);
}
}
}
}
即使在发出 STOP 命令后,目前 main 仍在继续其循环。有没有办法锁定 main 直到另一个线程释放它而不必在 main 中执行 wait()
?
您不想按照自己的方式构建它。您不希望线程在任意点停止;尝试恢复时可能会导致问题。相反,给线程明确的停止点。
例如,您可以创建一个工作线程,让程序的主线程管理命令并将指令委托给您的工作线程。 process
方法是一种 增量 工作量,例如读取大文件的一行。例如,假设这是您的辅助任务:
public abstract class Worker implements Runnable {
private final Object lock = new Object();
private final AtomicBoolean shouldWait = new AtomicBoolean();
protected abstract boolean processingIsComplete();
protected abstract void process();
protected abstract void cleanUpResources();
public Object getLock() {
return lock;
}
public void disable() {
shouldWait.set(false);
}
public void enable() {
shouldWait.set(true);
}
@Override
public void run() {
try {
while(!processingIsComplete()) {
while(!shouldWait.get()) {
synchronized(lock);
lock.wait();
}
}
process();
}
} catch(InterruptedException e) {
System.out.println("Worker thread stopped");
} finally {
cleanUpResources();
}
}
}
然后,修改/subclass worker 来真正做处理工作。然后,在您的主 class 中,您可以根据需要打开和关闭您的工作人员。这只是一个骨架,显然您可以将行为重构为多个方法,添加其他控件,例如读取工作线程的状态等:
public static void main (String[] args) throws Exception {
Worker worker = new WorkerImpl(/* whatever args are needed */);
Thread workerThread = new Thread(worker);
System.out.println("Starting process...");
worker.start();
Scanner sc = new Scanner(System.in);
while(true) {
System.out.printn("Please enter command: ");
String command = sc.nextLine();
if("END".equals(command)) {
System.out.println("Terminating program... ");
workerThread.interrupt();
break;
} else if ("GO".equals(command)) {
synchronized(worker.getLock()) {
System.out.println("Continuing worker thread... ");
worker.enable();
worker.getLock().notifyAll();
}
} else if ("STOP".equals(command)) {
synchronized(worker.getLock()) {
System.out.println("Stopping worker thread ");
worker.disable();
worker.getLock().notifyAll();
}
} else {
printCommandHelp();
}
}
};
进一步阅读:How to use wait and notify in Java?