【问题标题】:Stoping and starting a new thread after timer expires计时器到期后停止和启动新线程
【发布时间】:2014-10-17 16:39:04
【问题描述】:

这是我在 Stackoverflow 上的第一篇文章,显然我对线程了解不多。 它是一个控制台应用程序,事情是,当 main 方法启动时,计时器也会启动并且我的程序执行,它涉及从键盘获取信息并且效果很好。

计时器到期后,假设 20 秒后,它从 RemindTask 类调用 run() 并显示我在此期间收集的点数。 现在,我想再次选择启动不启动我的应用程序,主要方法。

事情是我的主要仍然会从键盘收集信息,因为它仍在执行,而不是来自我想要的 run() 方法的输入。 如果我放 System.exit(0),当然我不能在它之后启动一个新线程。 我如何通过这个,有没有办法在我的while循环中说“直到我的计时器没有过期才这样做”?还是什么?

static class RemindTask extends TimerTask {
        public void run() {
             char answer;
             System.out.println("Time expired! "+yourResult);
             /* System.exit(0);
                Thread t = new Thread();
                t.start(); */
             System.out.println("Do you continue? y/n");
             Scanner in = new Scanner(System.in);
             answer = in.nextLine().charAt(0);
                if(answer=='y'){
                System.out.println("Continue program");
                String[] args = {}; 
                Main.main(args); 
                }else
                System.out.println("Stoping program");
                System.exit(0); //Stops the AWT thread (and everything else)
      }

        }

static int yourResult;
public static void main(String[] args) {

        int seconds=20;
        timer = new Timer();
        timer.schedule(new RemindTask(), seconds * 1000);
        boolean contin = true;  


        while(contin == true){

        //...a bunch of code...
        //...Scanner in = new Scanner(System.in);..
        //...a bunch of code...

        }

【问题讨论】:

    标签: java multithreading timer


    【解决方案1】:

    停止线程并非易事。如何停止线程的简短答案是:不要从另一个线程中停止一个线程;相反,要求线程自行停止。这样做的原因是线程必须在安全的地方停止。例如,如果被停止的线程持有一个互斥锁,如果另一个线程也需要这个互斥锁,则可能会发生死锁。

    首先,最好不要使用 main 方法来轮询键盘。只需创建另一个线程来执行此操作;这使得以后创建一个新线程做同样的事情变得更容易。

    其次,你要做的就是将对主线程的Thread 对象的引用传递给你的RemindTask 线程。 Java 提供了一种方法Thread.stop() 来停止线程,但由于我上面给出的原因,它已被弃用。

    相反,您必须要求主线程停止。 Java 提供了一种标准方法来执行此操作。您在主线程的Thread 实例上调用Thread.interrupt()。然后,在主线程中定期调用静态方法Thread.interrupted()。如果它返回true,这意味着其他线程已经要求当前线程终止,您可以通过从run()方法返回干净地停止。

    【讨论】:

    • 谢谢,我稍后再试,但有没有办法做到这一点,就像看起来一样,简单的任务“在计时器到期后通过键盘输入再次启动程序”而不用线程?我看不出有什么办法。没有键盘输入 'y' 很简单,它只是在 System.out.println("Time expired! "+yourResult); 之后再次调用 main ,但是用这个输入的东西真的很麻烦。
    • “你在主线程上调用 Thread.interrupt()。然后,在主线程中......” - 你不是指派生/其他线程还是类似的东西?
    • @DanielGomes 不,它是按原样写的,尽管我可以写得更清楚。我已经重新制定了一点。
    • 好的,我正在尝试掌握线程,我发现您的回答非常有帮助。特别是关于Thread.stop() 的部分——我自己一直想知道;仅此解释就是我的 +1。
    【解决方案2】:

    如果不调用 RemindTask.run() 方法,很难找出问题所在。在代码的注释部分,在主方法循环内,您有一个构造函数调用,它也在 RemindTask.run() 内。也许这是问题的一部分?

    【讨论】:

    • 我不确定你的意思是什么,或者我是否理解答案,在我的主方法循环内的代码的注释部分中,我有一堆正在工作的代码。我会尽力解释得更好。方法和键盘输入在我的 while 循环中执行,20 秒后它调用 RemindTask.run() 和 sayz System.out.println("Time expired! "+yourResult); System.out .println("Do you continue? y/n"); 当我尝试插入 'y' 因为我想重复我的程序时,它仍然会在 main 中的 while 循环中为方法收集键盘输入,而不是将其存储在 char answer
    • 您似乎正在使用 System.in 打开两个扫描仪。这很奇怪。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多