【问题标题】:How to make a thread sleep from another thread in Java如何使一个线程从Java中的另一个线程休眠
【发布时间】:2011-06-28 12:40:26
【问题描述】:

我有两个执行线程(比如 Thread1 和 Thread2)。 Thread2 正在监听一个特定的事件,当事件发生时它想要停止 Thread1 的执行并触发一个动作。完成操作后,它需要从停止的位置继续执行 Thread1。

在 Java 中我应该采取什么样的方法来做到这一点?

【问题讨论】:

标签: java multithreading event-handling


【解决方案1】:

恕我直言,干净的方法是让 Thread1 定期轮询某个状态变量以查看它是否已被要求暂停。如果它被要求暂停,那么它应该暂停执行,等待某个锁被释放。

Thread2 应该通过更改共享状态变量的值来请求 Thread1 暂停,然后可能等待 Thread1 接受暂停请求,然后执行其操作并释放 Thread1 正在等待的锁。

简而言之,两个线程必须协作。据我所知,没有它的协作,就无法干净地暂停线程。

【讨论】:

    【解决方案2】:

    您(当然)需要引用您希望停止的线程。你可以通过调用'suspend'方法来暂停它:http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html#suspend() 在线程上。 同样,您可以调用 'resume' 让线程再次运行。

    但是,请注意,这极容易出现死锁问题,因为您不知道线程在哪里停止。

    【讨论】:

    • 不推荐使用suspend(与resume相同)
    • 当然它已被弃用,但它完全符合海报的要求。我不会从一个简短的问题来判断他的代码。做他所做的事情可能有很好的理由。
    • 没有理由拒绝投票。暂停/恢复是正确的模式,我们不能因为 Java 中的糟糕实现而责怪 Matthias。 并且 - 马蒂亚斯在他的回答中添加了警告。表明他完全意识到这些方法已被弃用以及为什么会这样。我们仍然可以使用这些方法,但我们必须非常谨慎地选择环境。
    【解决方案3】:

    您似乎需要在线程之间进行某种同步。我想你想让T1 不去睡觉,而是等到T2 执行操作。在这种情况下,您可以使用 Java 提供的任何同步原语。比如synchronized关键字:

    class T1 implements Runnable {
      private final Object lock;
    
      public T1(Object lock) {
        this.lock = lock;
      }
    
      public function run() {
        while(!currentThread().isInterrupted()) {
          waitForEvent();
          synchronized (lock) {
            // here T2 sleeps and wait until we perform event processing
          }
        }
      }
    }
    
    class T2 implements Runnable {
      private final Object lock;
    
      public T1(Object lock) {
        this.lock = lock;
      }
    
      public function run() {
        while(!currentThread().isInterrupted()) {
          synchronized (lock) {
            // do some work and release lock
          }
        }
      }
    }
    
    Object lock = new Object();
    new Thread(new T1(lock)).start();
    new Thread(new T2(lock)).start();
    

    顺便说一句,Thread#stop()Thread#suspend()Thread#resume() 方法已被弃用,不建议使用它们。

    【讨论】:

      【解决方案4】:

      在线程 2 中使用 join,在此处阅读更多信息 http://download.oracle.com/javase/tutorial/essential/concurrency/join.html

      【讨论】:

      • join 不会暂停引用的线程。它将一直等到线程停止执行,然后继续等待线程。
      • 谢谢,我记错了。 join 必须在线程 1 中使用,这不是这里的问题。
      • join 在这里不是一个选项,因为线程 1 和线程 2 都不会死(这是我的理解 - 线程 2 会继续听,对吗?)
      • 我现在看到了问题join 在这种情况下可能不是要走的路。
      【解决方案5】:

      您可以在Thread2 中保留对另一个线程的引用并暂停它。 但真正的问题是,如果它们必须相互等待运行,为什么还需要两个线程?

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 2020-04-30
      • 2010-12-13
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多