简体   繁体   English

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

[英]How to make another thread sleep in Java

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

You can't make another thread sleep.你不能让另一个线程休眠。 (You can use the deprecated suspend() method, but please don't). (您可以使用已弃用的suspend()方法,但请不要使用)。 This call:这个电话:

this.sleep(200);

will actually make the currently executing thread sleep - not the Thread referred to by "this".实际上会使当前正在执行的线程休眠 - 而不是“this”所指的Thread sleep is a static method - good IDEs will issue a warning over that line. 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 good thing 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 controlled way - at a point where you know it's going to do no harm.通过使用基于标志的系统,您可以以可控的方式入睡 - 在您知道不会造成伤害的时候。

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 等待其他工作完成。

Actually, to tell the thread to sleep longer , I suggest that your special method would memorize this fact into a volatile field.实际上,为了告诉线程休眠更长时间,我建议您的特殊方法将这个事实记住到一个 volatile 字段中。 Then, the thread of interest should read that variable, and sleep longer if set.然后,感兴趣的线程应该读取该变量,如果设置,则休眠更长时间。

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 ,但它可能会非常快,并且中断将发生在您的代码中的特殊点,您知道可以在不破坏事物的情况下停止......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM