【问题标题】:How does Thread.sleep() work when called from multiple threads从多个线程调用时 Thread.sleep() 如何工作
【发布时间】:2011-04-01 23:38:08
【问题描述】:

sleep() 是 Thread 类的静态方法。从多个线程调用时它是如何工作的。以及它如何确定当前的执行线程。 ?

或者可能是一个更通用的问题是如何从不同的线程调用静态方法?不会有并发问题吗?

【问题讨论】:

    标签: java multithreading static synchronization


    【解决方案1】:

    sleep 方法使当前线程休眠,因此如果您从多个线程调用它,它将使每个线程休眠。还有currentThread 静态方法可以让你获取当前正在执行的线程。

    【讨论】:

      【解决方案2】:

      Thread.sleep(long)java.lang.Thread 类中本地实现。这是其 API 文档的一部分:

       Causes the currently executing thread to sleep (temporarily cease 
       execution) for the specified number of milliseconds, subject to 
       the precision and accuracy of system timers and schedulers. The thread 
       does not lose ownership of any monitors.
      

      sleep 方法使调用它的线程休眠。(基于 EJP 的 cmets)确定当前执行的线程(调用它并使其休眠)。 Java 方法可以确定哪个线程正在执行通过调用Thread.currentThread()

      方法(静态或非静态)可以同时从任意数量的线程调用。只要你的方法是thread safe,就不会有任何并发​​问题。 只有当多个线程在没有适当同步的情况下修改类或实例的内部状态时,您才会遇到问题。

      【讨论】:

      • @naikus 线程类的实现说睡眠是本机方法。知道本机代码如何确定要休眠的线程吗?
      • @Naikus 。我想知道的是,静态方法中的代码如何在线程范围内运行。是否会有每个方法的副本加载到线程的堆栈中?
      • @YoK,我不确定,但也许它调用了另一个本地方法 Thread.currentThread() ;)。我相信你知道。
      • @JWhiz 不,不会有任何方法的副本,对于 java 方法,堆栈对于存储方法调用状态的每个方法调用都有一个“堆栈框架”。但这仅适用于 java 方法,不适用于本地方法。
      • 'sleep 方法确定当前正在执行的线程(调用它并使其进入睡眠状态)'。这是不正确的。除了调用操作系统的 sleep() 系统调用外,Thread.sleep() 不需要做任何事情。 sleep() 是一个系统调用,总是导致当前线程休眠。
      【解决方案3】:

      一个更通用的问题是如何从不同的线程调用静态方法?不会有并发问题吗?

      如果一个或多个线程修改共享状态,而另一个线程使用相同的状态,则只有潜在的并发问题。 sleep() 方法没有共享状态。

      【讨论】:

        【解决方案4】:

        它是如何计算当前的 执行线程?

        没必要。它只是调用操作系统,而操作系统总是让调用它的线程休眠。

        【讨论】:

          【解决方案5】:

          当虚拟机遇到sleep(long)-statement时,会中断当前运行的Thread。那一刻的“当前线程”始终是调用Thread.sleep() 的线程。然后它说:

          嘿!在这个线程中无事可做(因为我必须等待)。我将继续另一个线程。

          改变线程被称为“屈服”。 (注:您可以拨打Thread.yield();自行让步)

          所以,它不必弄清楚当前线程是什么。调用 sleep() 的始终是线程。 注意:可以通过调用Thread.currentThread();获取当前线程

          一个简短的例子:

          // here it is 0 millis
          blahblah(); // do some stuff
          // here it is 2 millis
          new Thread(new MyRunnable()).start(); // We start an other thread
          // here it is 2 millis
          Thread.sleep(1000);
          // here it is 1002 millis
          

          MyRunnablerun() 方法:

          // here it is 2 millis; because we got started at 2 millis
          blahblah2(); // Do some other stuff
          // here it is 25 millis;
          Thread.sleep(300); // after calling this line the two threads are sleeping...
          // here it is 325 millis;
          ... // some stuff
          // here it is 328 millis;
          return; // we are done;
          

          【讨论】:

            猜你喜欢
            • 2023-02-01
            • 2017-10-18
            • 1970-01-01
            • 2012-11-24
            • 1970-01-01
            • 2011-09-16
            • 1970-01-01
            • 1970-01-01
            • 2021-07-04
            相关资源
            最近更新 更多