Как заставить другой поток спать в Java

у меня есть класс, который расширяет поток. Этот поток при запуске тратит большую часть своего времени на сон, он выполнит проверку, если 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 ответов


вы не можете заставить другого потока сна. (Вы можете использовать устаревший suspend() метод, но, пожалуйста, не). Этот призыв:

this.sleep(200);

С в настоящее время выполнения нить сна-не то Thread называют "это". sleep является статическим методом-хорошие IDEs выдадут предупреждение по этой строке.

вы должны просто иметь флаг, говорящий "спать, пожалуйста", а затем сделать спящий поток проверить этот флаг, прежде чем делать работа.

это хороший то, что вы не можете заставить другой поток спать. Предположим, что это синхронизированный метод - это означало бы, что вы держите замок во время сна, заставляя всех остальных пытаться получить тот же самый замок. Ничего хорошего. Используя систему на основе флагов, вы можете спать в контролируемые путь-в точке, где вы знаете, что это не причинит вреда.


добавьте это в свой поток:

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

таким образом, вы можете заставить спящего ждать, пока другая работа не будет завершена.


на самом деле, чтобы сказать поток спать больше, Я предлагаю, чтобы ваш специальный метод запомнил этот факт в летучее поле. Затем поток интереса должен прочитать эту переменную и спать дольше, если он установлен.

теперь, чтобы заставить его спать сразу, вы должны прервать поток. Это вызовет исключение, чтобы остановить текущую обработку. Теперь ты должен разобраться с этим ... Подумай, действительно ли это то, что ты ... хотеть.

другим решением было бы, в активности потока normal, также опросить переменную, как в первом случае, и спать, если она установлена. Это было бы не вызывает немедленного сна, но это может быть довольно быстро, и прерывание будет в особых точках вашего кода, где вы знаете, что можете остановиться, не нарушая вещи ...