我声明我读过线程,但我从未使用过。 所以我问你:)
我有两个主题:A
和B
,
其中A
管理GUI,B
管理逻辑。
我会从A
开始。
然后当A
绘制GUI时,我会暂停它,等待到达X点的B
进入run方法。
当B
到达X点运行方式时,我会暂停B
,然后恢复A
。
A
和B
共享一些变量来管理GUI和逻辑......
我可以这样做吗?如果有,怎么样? :)
答案 0 :(得分:20)
wait()
- 使当前线程等待,直到另一个线程调用notify()
方法或此对象的notifyAll()
方法。
notify()
- 唤醒正在此对象监视器上等待的单个线程。
答案 1 :(得分:13)
您可以使用Object类的wait
和notify
方法来阻止线程,但要正确起来可能会很棘手。这是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
}
}
};
(有关我们在调用wait
和notifyAll
时如上所述同步的原因的详细信息,请参阅the Java tutorial on the subject。)
如果另一个Thread调用此Runnable的pause()
方法,则运行runnable的Thread将在到达while循环的顶部时阻塞。
请注意,无法在任意点暂停线程。你需要Thread来定期检查它是否应该暂停并阻塞它自己。
答案 2 :(得分:4)
我希望您不需要暂停GUI线程。操作系统将负责这一点,并且需要准备好响应以防用户做某事。
另一个想法是确保共享变量在两个线程之间正确同步。我最近尝试回答了与此相关的问题,请参阅here。
答案 3 :(得分:3)
您可以使用CountDownLatch
。当线程A必须等待线程B将调用countDownLatchInstance.await();
当B到达X点时将调用countDownLatchInstance.countDown()
;允许A继续执行流程。
当你说
时A管理GUI
我希望你不要参考UI/Main Thread
,
答案 4 :(得分:1)
这就是我让线程等待并通知为我工作的方式:
public class Main {
public static void main(String[] args) {
final Object lock = new Object();
MyThread t = new MyThread();
t.lock = lock;
t.run();
while (true) {
try {
synchronized (lock) {
lock.wait();
}
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MyThread extends Thread {
Object lock;
@Override
public void run() {
JFrame fr = new JFrame("Anothing");
JButton btn = new JButton("Next");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
synchronized (lock) {
lock.notify();
}
}
});
fr.setLayout(new FlowLayout());
fr.add(btn);
fr.setSize(400, 400);
fr.setVisible(true);
}
}
然后,每当我按下按钮,另一个线程醒来,执行一轮并等待新的点击。
答案 5 :(得分:1)
job-name:
script:
- echo "i am potato"
rules:
- if: '$CI_COMMIT_BRANCH != "potato"'
只需将Mutex对象添加到您的线程并创建getter。
public class Mutex {
private final AtomicBoolean lock;
private final Object mutex;
public Mutex(boolean lock) {
this.lock = new AtomicBoolean(lock);
this.mutex = new Object();
}
public void step() {
if (lock.get()) synchronized(mutex) {
try {
mutex.wait();
} catch (InterruptedException ex) {}
}
}
public void lock() {
lock.set(true);
}
public void unlock() {
lock.set(false);
synchronized(mutex) {
mutex.notify();
}
}
}
如果您想暂停线程,只需调用
public class MyThread extends Thread {
private final Mutex mutex;
public MyThread() {
this.mutex = new Mutex(false);
}
public Mutex getMutex() {
return this.mutex;
}
@Override
public void run() {
while (!isInterrupted()) {
mutex.step();
// do your code
}
}
}
如果要恢复线程,只需调用
myThread.getMutex().lock();
答案 6 :(得分:0)
不推荐使用暂停和恢复线程的java原语。了解如何实现最佳效果 - http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html 检查你如何做相当于暂停& amp;恢复
我应该使用什么而不是
Thread.suspend
和Thread.resume
?与
Thread.stop
一样,谨慎的做法是让“目标线程”轮询一个变量,指示线程的所需状态(活动或暂停)。当所需状态暂停时,线程将使用Object.wait
等待。当线程恢复时,使用Object.notify
通知目标线程。
示例代码在相同的答案中给出,以帮助您实现此目的。