Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当用户按下exit时,如何中断线程并要求它完成其工作?_Java_Multithreading - Fatal编程技术网

Java 当用户按下exit时,如何中断线程并要求它完成其工作?

Java 当用户按下exit时,如何中断线程并要求它完成其工作?,java,multithreading,Java,Multithreading,下面的代码段是一个名为“Foo”的线程,它休眠1分钟,然后将在1分钟内键入的数据复制到日志文件中 while(isStarted) { try { Thread.sleep(60000); // sleep for 1 minute ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();

下面的代码段是一个名为“Foo”的线程,它休眠1分钟,然后将在1分钟内键入的数据复制到日志文件中

         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条)
因此,无论何时创建Thread1实例,都可以向其传递Java对象(new Object())。读卡器线程可以使用object.wait(60*1000)进入睡眠状态;因此,如果在1分钟内未调用object.notify(),它将最多休眠1分钟。若在此期间调用object.notify(),线程将立即恢复

所以,无论何时用户想要退出应用程序,都可以调用object.notify();这将恢复读卡器线程


如果我因为英语不好而未能向您解释解决方案,请让我知道。我将为您提供一个代码示例。

您已经完成了一部分

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