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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1508278/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:49:20  来源:igfitidea点击:

How to make another thread sleep in Java

javamultithreading

提问by A Hymanson

I have a class that extends Thread. This thread when running spends most of it's time sleeping, it will perform a check, if true perform a simple action, then sleep for 1/2 second and repeat.

我有一个扩展线程的类。这个线程在运行时大部分时间都在休眠,它会执行检查,如果为真则执行一个简单的操作,然后休眠 1/2 秒并重复。

The class also has a public method that is called by other threads. If this is called I want the thread to sleep for longer if it is already sleeping or just sleep immediately if it isn't. I tried to have this.sleep but it seems that this still sleeps the current thread and it complains that the method sleep is static and should be accesses statically.

该类还有一个由其他线程调用的公共方法。如果这被调用,我希望线程在它已经休眠的情况下休眠更长时间,如果不是,则立即休眠。我试图让 this.sleep 但它似乎仍然使当前线程休眠,并且它抱怨方法 sleep 是静态的,应该静态访问。

This program shows my problem, when CauseSleep is called I want it to stop printing numbers until that sleep has finished.

这个程序显示了我的问题,当调用 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) {
            }
        }
    }
}

The output I get is

我得到的输出是

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

回答by Jon Skeet

You can't make another thread sleep. (You can use the deprecated suspend()method, but please don't). This call:

你不能让另一个线程休眠。(您可以使用已弃用的suspend()方法,但请不要)。这个电话:

this.sleep(200);

will actually make the currently executingthread sleep - not the Threadreferred to by "this". sleepis a static method - good IDEs will issue a warning over that line.

实际上会使当前正在执行的线程休眠 - 而不是Thread“this”所指的。sleep是一种静态方法 - 好的 IDE 会在该行上发出警告。

You should just have a flag saying "sleep please" and then make the sleeper thread check that flag before doing any work.

你应该有一个标志说“请睡觉”,然后在做任何工作之前让睡眠线程检查该标志。

It's a goodthing that you can't cause another thread to sleep. Suppose it's in a synchronized method - that would mean you'd be holding a lock while sleeping, causing everyone else trying to acquire the same lock to block. Not a good thing. By using a flag-based system, you get to sleep in a controlledway - at a point where you know it's going to do no harm.

你不能导致另一个线程休眠是一件好事。假设它在一个同步方法中——这意味着你会在睡觉时持有一个锁,导致其他人试图获取相同的锁被阻塞。不是什么好事。通过使用基于标志的系统,您可以以可控的方式入睡- 在您知道不会造成伤害的时候。

回答by Aaron Digulla

Add this to your thread:

将此添加到您的线程:

public AtomicBoolean waitLonger = new AtomicBoolean  ();
public Object lock = new Object ();

In run():

run()

synchronized (lock) {
    if (waitLonger.get ()) {
        lock.wait ();
    }
}

In the other thread:

在另一个线程中:

synchronized (lock) {
try {
    sleeper.waitLonger.set(true);
    ...
    lock.notify();
    sleeper.waitLonger.set(false);
}

This way, you can make the sleeper wait until the other work has completed.

这样,您可以让 sleeper 等待其他工作完成。

回答by KLE

Actually, to tell the thread to sleep longer, I suggest that your special method would memorize this fact into a volatile field. Then, the thread of interest should read that variable, and sleep longer if set.

实际上,为了告诉线程休眠更长时间,我建议您的特殊方法将这个事实记住到一个 volatile 字段中。然后,感兴趣的线程应该读取该变量,如果设置,则休眠更长时间。

Now, to cause it to sleep immediately, you have to interrupt the thread. That will throw an exception, to stop the current processing. Now you have to deal with this ... Think if this is really what you want.

现在,要使其立即休眠,您必须中断线程。这将引发异常,以停止当前处理。现在你必须处理这个......想想这是否真的是你想要的。

Another solution would be, in the thread normal's activity, to also poll the variable like in the first case, and to sleep if it is set. This would not cause an immediate sleep, but it could be pretty fast, and the interruption would be at special points in your code where you know you can stop without breaking things ...

另一种解决方案是,在线程正常的活动中,也像第一种情况一样轮询变量,如果设置了则休眠。这不会导致立即 sleep,但它可能会非常快,并且中断将发生在您的代码中的特殊点,您知道可以在不破坏事物的情况下停止......