【问题标题】:How to stop code after Thread's sleep() method executing immediately如何在线程的 sleep() 方法立即执行后停止代码
【发布时间】:2016-07-07 12:55:35
【问题描述】:

我试图通过调用 Thread 类的 sleep() 方法来暂停我的部分程序的执行几秒钟。但是,当我尝试此操作时,此调用之后立即出现的代码仍会立即执行。例如,如果我有代码:

Thread compoundThread = new Thread(new Runnable()
{                       
    public void run() 
    {
        try 
        {
            Thread.currentThread().sleep(2000);
        } 
        catch (InterruptedException e) 
        {
            // TODO Auto-generated catch block
            Thread.currentThread().interrupt();
        }               
    }

});

compoundThread.start();

System.out.println("line 15")

第 15 行立即打印。有没有办法解决这个问题?我认为sleep() 方法的整个想法是暂停执行。

根据 Philipp 的评论进行编辑

while (totalNoOfPhase1Trials > 399)
{           //
                Phase1Trial phase1Trial = new Phase1Trial(numberOfElements, elementColors);

                displayComplexStimulus(phase1Trial.getComplexStimulus());
                validate();

                Thread compoundThread = new Thread(new Runnable(){

                    public void run() {
                        try {
                            Thread.currentThread().sleep(2000);
                            System.out.println("line 226");
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block

                        }


                    }

                });



                compoundThread.start();     
                try {
                    compoundThread.join();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

displayCompoundStimulus 方法显示一组jlabels 没有延迟,当我不包括你刚才提到的我让线程休眠的代码时。但是,当我包含使线程进入睡眠状态的代码时,图像的显示也会延迟两秒钟,这很奇怪,因为 Thread.sleep() 在图像显示后才被执行。

【问题讨论】:

  • 能否请您包含代码的行号
  • 我不知道怎么做,但是 System.out.println("line 15") 是第 15 行。
  • 一个线程将在另一个执行上下文中执行;你期待什么?
  • 那么你是说在 run 方法中有 print 行吗?

标签: java multithreading thread-sleep


【解决方案1】:

代码的行为与实现相同。您正在运行您的主线程,该线程启动另一个线程,该线程休眠 2000 毫秒。

所以你的主线程是这样的:

  1. 启动复合线程
  2. 打印出来
  3. 完成主线程

根据您想要实现的目标,您可以删除整个线程并执行以下操作:

try {
   Thread.sleep(2000);
} catch (InterruptedException e) {
   // should not happen, you don't interrupt                     
}
System.out.println("line 15");

否则你可以将输出移动到线程的run方法中:

Thread compoundThread = new Thread(new Runnable(){

    public void run() {
        try {
            Thread.sleep(2000);
            System.out.println("line 15");
        } catch (InterruptedException e) {
            // do whatever has to be done
        }
    }
});

compoundThread.start();

// you might want to wait until compoundThread is done
compoundThread.join();

更新:基于您对延迟输出的评论

如果你使用以下代码:

public static void main(String[] args) {
    System.out.println("Hello");
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // should not happen, you don't interrupt
    }
    System.out.println("World");
}

输出将是“Hello”,然后是“World”两秒钟。线程将恰好休眠两秒钟。

【讨论】:

  • @siegi 该死的我错过了那个解决方案:)
  • 您关于删除整个线程的建议给我带来了问题,因为它也将 Thread.sleep() 行之前的打印语句的执行延迟了两秒钟,我不知道为什么.
  • 你能提供你的整个代码来理解你的意思吗?
  • 对不起,不是打印声明,我是指我展示的图像。我的代码在 jpanel 中显示了一些 jlabel。但是,当我通过使用 Thread.sleep() 使主线程进入睡眠状态时,现在,不仅打印语句,而且图像显示也延迟了两秒,尽管图像应该在之前显示线程进入睡眠状态,这是没有意义的。图像显示没有延迟,但是当我在显示图像的行之后添加代码行: Thread.sleep() 时,图像显示也会延迟两秒。
  • @lb91:我猜你在Thread.sleep() 之前使用的是print 而不是println。 Java(准确地说是PrintWriter)仅在您使用println 时才会自动刷新。在执行Thread.sleep() 之前使用System.out.flush() 强制刷新。另请参阅this question。
【解决方案2】:

这里的compoundThread 是一个新的线程对象。您的 line 15 是通过 main 方法执行的。因此,当您启动compoundThread.start() 时,会创建一个新线程并独立于您的主线程启动。

如果您想减慢主线程的速度,只需在可运行目标代码之外使用Thread.sleep(2000)。

【讨论】:

  • 我发现当我这样做时,它最终也会将 Thread.sleep(2000) 之前的代码执行速度减慢两秒。例如,如果我在 Thread.sleep(2000) 方法之前放置一个 print 语句,然后在其后放置一个 print 语句,这两个 print 语句将同时打印,这对我来说毫无意义。
  • @lb91 就是这样。这取决于您想要sleep 的时间和线程。正如其他答案指出的那样,如果你在外面使用它,它会减慢你的主线程,在可运行的内部然后它会减慢线程的特定实例。
【解决方案3】:

主线程是开始运行您的 main 方法的线程。

然后您的 main 方法会创建一个新的 Thread 对象并调用 compoundThread.start();,这会导致第二个线程开始执行。

紧接着,没有停止主线程继续执行并到达打印语句。因此line 15 正在由主线程打印。

您启动的第二个线程休眠 2 秒然后终止。如果您在sleep 调用之后将打印语句放在线程的run 方法中,那么在打印line 15 之前会有2 秒的暂停。

【讨论】:

  • 感谢您的详细解释。我现在明白了。
【解决方案4】:

你原来的线程(主线程)启动一个新线程,新线程休眠两秒。原始线程没有,这就是它立即打印“第 15 行”的原因。因此,Sandeep 的建议虽然很简洁,但如果您理解并正确应用它,应该会奏效。另一种明显的可能性是将System.out.println 语句放在compoundThread 的run 方法中。

【讨论】:

    【解决方案5】:

    Screenshot

    看看并告诉我它是否有效

    【讨论】:

      【解决方案6】:

      我建议你使用简单的

      thread.sleep(2000)
      

      【讨论】:

      • @Sandeep:欢迎来到 StackOverflow!您可以随时编辑您的答案(使用下面的链接)。特别是对于发布代码,cmets 不太适合。直接在答案中使用代码块。请参阅Markdown help 了解如何正确格式化。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-04
      • 2014-11-22
      相关资源
      最近更新 更多