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

时间:2009-10-02 08:15:17

标签: java multithreading

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

该类还有一个由其他线程调用的公共方法。如果调用它,我希望线程在睡眠时睡眠时间更长,如果不是则立即睡觉。我试图让这个.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 个答案:

答案 0 :(得分:24)

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

this.sleep(200);

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

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

这是的事情,你不能让另一个线程睡觉。假设它是在同步方法中 - 这意味着你在睡觉时持有一个锁,导致其他人试图获得相同的锁来阻止。不是一件好事。通过使用基于标志的系统,您可以以受控方式进入睡眠状态 - 在您知道它不会造成伤害的位置。

答案 1 :(得分:3)

将此添加到您的主题:

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);
}

这样,你可以让睡眠者等到其他工作完成。

答案 2 :(得分:1)

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

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

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