Я только что обновил этот ответ , чтобы включить SCCE .
Рабочие вызывают pauseIfNeeded в WorkerPauseManager. Если менеджер приостанавливается, когда рабочий поток вызывает pauseIfNeeded (), мы вызываем wait (), который сообщает вызывающему потоку ждать, пока другой поток не вызовет notify () или notifyAll () для ожидаемого объекта. Это происходит, когда поток диспетчера событий Swing вызывает play () для менеджера, который, в свою очередь, вызывает notifyAll ().
Обратите внимание, что у вас должна быть синхронизированная блокировка для объекта, для которого вы вызываете wait () или notify (). Поскольку методы в WorkerPauseManager синхронизированы, все синхронизированные методы получают синхронизированную блокировку на самом WorkerPauseManager.
import javax.swing.*;
import java.awt.event.ActionEvent;
/**
* @author sbarnum
*/
public class WorkerPauseManagerTest {
public static void main(String[] args) {
final WorkerPauseManager pauseManager = new WorkerPauseManager();
new Worker("Worker 1", pauseManager).start();
new Worker("Worker 2", pauseManager).start();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JToggleButton playPauseButton = new JToggleButton(new AbstractAction("Pause") {
public void actionPerformed(final ActionEvent e) {
JToggleButton source = (JToggleButton) e.getSource();
if (source.isSelected()) {
pauseManager.start();
source.setText("Pause");
} else {
pauseManager.pause();
source.setText("Play");
}
}
});
playPauseButton.setSelected(true); // already running
JOptionPane.showMessageDialog(null, playPauseButton, "WorkerPauseManager Demo", JOptionPane.PLAIN_MESSAGE);
System.exit(0);
}
});
}
private static class Worker extends Thread {
final String name;
final WorkerPauseManager pauseManager;
public Worker(final String name, final WorkerPauseManager pauseManager) {
this.name = name;
this.pauseManager = pauseManager;
}
@Override
public void run() {
while (!Thread.interrupted()) {
try {
pauseManager.pauseIfNeeded();
System.out.println(name + " is running");
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public static final class WorkerPauseManager {
private boolean paused;
public synchronized void pauseIfNeeded() throws InterruptedException {
if (paused) wait();
}
public synchronized void pause() {
this.paused = true;
}
public synchronized void start() {
this.paused = false;
notifyAll();
}
}
}