Java 当用户按下exit时,如何中断线程并要求它完成其工作?
下面的代码段是一个名为“Foo”的线程,它休眠1分钟,然后将在1分钟内键入的数据复制到日志文件中Java 当用户按下exit时,如何中断线程并要求它完成其工作?,java,multithreading,Java,Multithreading,下面的代码段是一个名为“Foo”的线程,它休眠1分钟,然后将在1分钟内键入的数据复制到日志文件中 while(isStarted) { try { Thread.sleep(60000); // sleep for 1 minute ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();
while(isStarted) {
try {
Thread.sleep(60000); // sleep for 1 minute
ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();
int result = copy.copyToLogFile(keyStrokeList);
System.out.println(result);
} catch(Exception exc) {
exc.printStackTrace();
}
}
您应该在两个线程之间使用共享对象来实现等待/通知模式,而不是thread.sleep(..)方法 在您的情况下,有2个线程:
- 以1分钟的间隔读取缓冲区。(1)
- 它将首先接收“退出”事件。(第2条)
如果我因为英语不好而未能向您解释解决方案,请让我知道。我将为您提供一个代码示例。您已经完成了一部分
while(isStarted) {
try {
Thread.sleep(60000); // sleep for 1 minute
} catch(InterruptedException exc) {
exc.printStackTrace();
}
ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();
int result = copy.copyToLogFile(keyStrokeList);
System.out.println(result);
}
您还应该知道,JVM将不会退出,直到所有非守护进程线程都完成(在正常关闭情况下)。这意味着您可以调用System.exit(0)
,直到记录器线程终止,JVM才会终止
您可以使用它,但是附加一个可以在记录器线程上调用
dispose
方法的函数…只是一个想法这里有一个相当简单的测试用例来展示一种方法:
public class InterruptTest
{
@Test
public void test() throws InterruptedException
{
//Create the logging thread and start it
LogRunnable runnable = new LogRunnable();
Thread t = new Thread(runnable);
t.start();
//Wait some time
Thread.sleep(3500);
System.out.println("User has pressed exit, starting shutdown");
//Tell the runnable to shut down
runnable.halt();
//Interrupt the thread to wake it up
t.interrupt();
//Wait until thread terminates
t.join();
System.out.println("Exiting");
}
private static class LogRunnable implements Runnable
{
private static final int SLEEPMS = 2000;
private boolean isStarted = true;
private int runCount = 1;
public void halt()
{
this.isStarted = false;
}
public void run()
{
while(isStarted)
{
try
{
Thread.sleep(SLEEPMS);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
catch(Exception exc)
{
exc.printStackTrace();
}
//Do work
System.out.println("Work done " + runCount++);
}
}
}
}
输出:
Work done 1
User has pressed exit, starting shutdown
Interrupted
Work done 2
Exiting
- 当用户按下exit键时,您会发出信号让主线程开始关闭所有内容(在测试用例中,它只是等待一段时间)
- 日志线程被告知停止并通过-调用被唤醒
- 日志线程会在
中唤醒,在捕获后完成代码并终止InterruptedException
- 日志线程终止后,主线程从
-调用返回并终止join()
新线程(“Foo”)。中断不唤醒并执行挂起的任务?不,您还没有启动线程,并且仍然需要克服循环条件的问题。但是是的,对logger线程中断方法实例的调用将导致sleep方法提前终止。如果我将条件设为false并对foo的实例调用中断,那么睡眠后的语句会执行吗?是的。它的作用就像sleep方法正常返回一样,sleep后的代码将执行,循环条件将被取消,循环将存在,线程将终止join只是确保线程已完成(最后一次写入操作已完成)。当线程作为守护进程线程启动时,这尤其有用
public class InterruptTest
{
@Test
public void test() throws InterruptedException
{
//Create the logging thread and start it
LogRunnable runnable = new LogRunnable();
Thread t = new Thread(runnable);
t.start();
//Wait some time
Thread.sleep(3500);
System.out.println("User has pressed exit, starting shutdown");
//Tell the runnable to shut down
runnable.halt();
//Interrupt the thread to wake it up
t.interrupt();
//Wait until thread terminates
t.join();
System.out.println("Exiting");
}
private static class LogRunnable implements Runnable
{
private static final int SLEEPMS = 2000;
private boolean isStarted = true;
private int runCount = 1;
public void halt()
{
this.isStarted = false;
}
public void run()
{
while(isStarted)
{
try
{
Thread.sleep(SLEEPMS);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
catch(Exception exc)
{
exc.printStackTrace();
}
//Do work
System.out.println("Work done " + runCount++);
}
}
}
}
Work done 1
User has pressed exit, starting shutdown
Interrupted
Work done 2
Exiting