如何在Java中让一个线程从另一个线程休眠

5

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

在Java中,应该采取什么样的方法来实现这一点?


可能是重复的问题:如何在Java中使另一个线程休眠 - Tyler
5个回答

8

在我看来,最好的方法是让Thread1定期轮询某个状态变量,以查看是否已被要求暂停。如果被要求暂停,则应该暂停执行,并等待释放某个锁定。

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

简而言之,两个线程必须进行协作。我所知道的方法中没有一种可以在没有协作的情况下干净地暂停线程。


5

1
suspend已被弃用(恢复也是如此)。 - RMT
当然,它已经过时了,但它确实可以做到发帖者所要求的。我不会仅仅因为一个简短的问题就评判他的代码。可能有非常好的理由来做他所做的事情。 - Mathias Schwarz
3
没有下投票的理由。暂停/恢复是正确的模式,我们不能因为Java中的实现不好而责怪Matthias。此外,Matthias在他的回答中加入了警告,表明他完全知道这些方法已经过时以及为什么会这样。我们仍然可以使用这些方法,但必须非常谨慎地选择环境。 - Andreas Dolk

2

看起来你需要线程之间的某种同步。我想你希望 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()已经被弃用,不建议使用它们。


1

join不会暂停所引用的线程。它将等待线程停止执行,然后继续等待的线程。 - Mathias Schwarz
谢谢,我记错了。"join"必须在线程1中使用,这不是问题所在。 - bingjie2680
这里不适用 join,因为无论是线程1还是线程2都不会死亡(至少我是这样理解的——线程2将继续监听,对吗?) - Andreas Dolk
我现在明白了,在这种情况下,join 可能不是解决问题的方法。 - adamjmarkham

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

http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html#suspend() 已被弃用。 - Bombe
1
同意 - 听起来你可能在误用线程,你的架构可能需要彻底改进。 - tofarr
1
这里没有提到suspend - Giann
-1 是因为 (a) 我们不想 暂停 线程 2,(b) pause 不是 Thread 中的方法,(c) 真正的 问题在上面已经被问过了。 - Andreas Dolk
应该涵盖了:http://download.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html - Giann
@Andreas_D 我没有使用动词“pause”来指代任何方法。 - Giann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接