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

7
我有一个继承了Thread的类。当这个线程运行时,大部分时间都在睡眠,它会执行一次检查,如果为真则执行简单操作,然后睡眠半秒钟并重复执行。
该类还有一个公共方法,被其他线程调用。如果调用此方法,则希望线程在已经睡眠的情况下延长睡眠时间或者立即进入睡眠状态(如果尚未睡眠)。我试图使用this.sleep,但似乎仍然使当前线程进入睡眠状态,并且表示该方法sleep是静态的并且应该使用静态访问。
该程序展示了我的问题,当调用CauseSleep时,我希望它停止打印数字,直到该休眠完成。
public class Sleeper {
    public static void main(String[] args) {
        new Sleeper();
    }
    public Sleeper() {
        System.out.println("Creating T");
        T t = new T();
        System.out.println("Causing sleep");
        t.CauseSleep();
        System.out.println("Sleep caused");
    }
    public class T extends Thread {
        public T() {
            this.start();
        }
        public void run() {
            for (int i = 0; i < 30; i++) {
                System.out.println("T Thread: " + i);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
            }
        }
        public void CauseSleep() {
            try {
                this.sleep(2000);
            } catch (InterruptedException e) {
            }
        }
    }
}

我得到的输出是:
Creating T
Causing sleep
T Thread: 0
T Thread: 1
T Thread: 2
T Thread: 3
T Thread: 4
T Thread: 5
T Thread: 6
T Thread: 7
T Thread: 8
T Thread: 9
T Thread: 10
T Thread: 11
T Thread: 12
T Thread: 13
T Thread: 14
T Thread: 15
T Thread: 16
T Thread: 17
T Thread: 18
Sleep caused
T Thread: 19
T Thread: 20
T Thread: 21
T Thread: 22
T Thread: 23
T Thread: 24
T Thread: 25
T Thread: 26
T Thread: 27
T Thread: 28
T Thread: 29
3个回答

25

您无法让另一个线程休眠。(您可以使用已弃用的suspend()方法,但请不要这样做)。此调用:

this.sleep(200);

实际上会使当前执行的线程休眠 - 而不是由"this"引用的Threadsleep是一个静态方法 - 好的IDE将在该行上发出警告。

您应该有一个标志,表示“请休眠”,然后使睡眠线程在执行任何工作之前检查该标志。

不能让另一个线程休眠是一件好事情。假设它在同步方法中 - 这意味着您在休眠时持有锁,导致其他所有尝试获取相同锁的人都被阻塞。这不是一件好事情。通过使用基于标志的系统,您可以在可控的方式下休眠 - 在您知道不会造成任何损害的时间点进行休眠。


4
将此内容添加到您的线程中:
public AtomicBoolean waitLonger = new AtomicBoolean  ();
public Object lock = new Object ();

run()函数中:
synchronized (lock) {
    if (waitLonger.get ()) {
        lock.wait ();
    }
}

在另一个线程中:
synchronized (lock) {
try {
    sleeper.waitLonger.set(true);
    ...
    lock.notify();
    sleeper.waitLonger.set(false);
}

这样做可以让休眠程序等待其他任务完成后再执行。

1

实际上,要让线程“睡得更久”,我建议您的特殊方法将此事实记忆到易失性字段中。然后,感兴趣的线程应读取该变量,并在设置时睡眠更长时间。

现在,要使其“立即休眠”,您必须中断线程。这将引发异常以停止当前处理。现在您必须处理这个问题...请考虑一下这是否是您真正想要的。

另一个解决方案是,在线程正常活动期间,像第一种情况一样轮询变量,并在设置时休眠。这不会导致“立即休眠”,但它可能非常快速,并且中断将在您知道可以停止而不破坏事物的代码的特殊点处进行...


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