如何暂停然后恢复一个线程?

Teo*_*Teo 40 java multithreading

我声明我读过线程,但我从未使用过.所以我问你:)

我有两个线程:AB,其中A管理GUI和B管理逻辑.

我会先说A.

然后在A绘制GUI时,我会暂停它,等待B到达X点进入run方法.

B达到X点进入运行方法时,我暂停B,然后恢复A.

AB共享一些变量来管理GUI,逻辑......

我可以做吗?如果有,怎么样?:)

Din*_*mar 23

使用wait()notify()方法:

wait() - 使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法.

notify() - 唤醒正在等待此对象监视器的单个线程.

  • 我建议使用`Semaphore`来避免`synchronized`和`wait` /`notify`中常见的陷阱. (5认同)

meg*_*lop 15

您可以使用Object类的waitnotify方法来阻止线程,但要正确起来可能很棘手.这是Runnable中无限循环内的一个示例:

public class Example implements Runnable {
    private volatile boolean running = true;
    private volatile boolean paused = false;
    private final Object pauseLock = new Object();

    @Override
    public void run() {
        while (running) {
            synchronized (pauseLock) {
                if (!running) { // may have changed while waiting to
                    // synchronize on pauseLock
                    break;
                }
                if (paused) {
                    try {
                        synchronized (pauseLock) {
                            pauseLock.wait(); // will cause this Thread to block until 
                            // another thread calls pauseLock.notifyAll()
                            // Note that calling wait() will 
                            // relinquish the synchronized lock that this 
                            // thread holds on pauseLock so another thread
                            // can acquire the lock to call notifyAll()
                            // (link with explanation below this code)
                        }
                    } catch (InterruptedException ex) {
                        break;
                    }
                    if (!running) { // running might have changed since we paused
                        break;
                    }
                }
            }
            // Your code here
        }
    }

    public void stop() {
        running = false;
        // you might also want to interrupt() the Thread that is 
        // running this Runnable, too, or perhaps call:
        resume();
        // to unblock
    }

    public void pause() {
        // you may want to throw an IllegalStateException if !running
        paused = true;
    }

    public void resume() {
        synchronized (pauseLock) {
            paused = false;
            pauseLock.notifyAll(); // Unblocks thread
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

(关于为什么我们需要如上图所示同步,同时呼吁更多的信息waitnotifyAll,看到关于这个问题的Java教程.)

如果另一个Thread调用此Runnable的pause()方法,则运行runnable的Thread将在到达while循环的顶部时阻塞.

请注意,无法在任意点暂停线程.如果是这样,您需要Thread定期检查是否应该暂停并阻止自身.

  • @DrBDOAdams`wait`和`notify`必须**始终**在`synchronized`块中调用.见[here](http://stackoverflow.com/questions/2779484/why-must-wait-always-be-in-synchronized-block)和[here](https://docs.oracle.com/javase/教程/本质/并发/ guardmeth.html).实际上,如果不这样做,将抛出`IllegalMonitorStateException`.注意,当调用`wait()`时,当前线程将放弃它在该对象上持有的锁,允许其他线程获取它. (2认同)