我已经使用wait和notify同步了这段代码,但现在当我通过点击wait按钮调用wait()时程序停止执行(程序挂起)。请帮忙,不建议我使用不同的链接,请修改此代码并回答。
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Main extends JFrame implements ActionListener, Runnable {
JLabel time = new JLabel();
JButton wait = new JButton("wait");
JButton notify = new JButton("notify");
Thread count = new Thread(this);
int sec=0;
public static void main(String arg[]) {
new Main();
}
public Main() {
super("Counter");
setSize(250,100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setVisible(true);
add(time);
add(wait);
add(notify);
notify.setEnabled(false);
wait.addActionListener(this);
notify.addActionListener(this);
count.start();
}
public void actionPerformed(ActionEvent e) {
synchronized(count) {
if(e.getSource()==wait) {
try
{
count.wait();
wait.setEnabled(false);
notify.setEnabled(true);
}
catch (Exception e1) {
e1.printStackTrace();
}
}
else if(e.getSource()==notify) {
count.notify();
wait.setEnabled(true);
notify.setEnabled(false);
}
}
}
public void run() {
synchronized (this) {
while(true) {
time.setText(String.format("seconds=%d",sec));
try
{
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
sec++;
}
}
}
}
答案 0 :(得分:1)
您致电wait()
时阻止了EDT。当你尝试notify()
时,它不会起作用,因为负责按钮事件(EDT)的线程已经在等待。您必须在另一个主题上调用notify()
。
public void actionPerformed(ActionEvent e) {
synchronized(count) {
if(e.getSource()==wait) {
try
{
count.wait(); // start blocking this thread
wait.setEnabled(false); // im pretty sure this doesnt get called until notified either
notify.setEnabled(true);
}
catch (Exception e1) {
e1.printStackTrace();
}
} else if(e.getSource()==notify) {
count.notify(); // will never get called cause this thread is blocked, waiting to be notified by another thread
wait.setEnabled(true);
notify.setEnabled(false);
}
}
}
答案 1 :(得分:1)
等待"等待"单击按钮,在事件调度线程上调用actionPerformed
。该线程不得被阻止,否则Swing将停止运行并且无法处理任何其他事件。因此,您不能在该主题上调用wait()
。
如果你想要"等待"按钮导致其他一些线程停止处理(也许你希望它停止更改"时间"文本?),你需要让你的actionPerformed
方法与其他线程进行通信以某种方式;设置另一个线程定期检查的共享volatile
变量可能就足够了。但是actionPerformed
需要快速返回。
答案 2 :(得分:0)
您需要阅读与java并发相关的快速且易于学习的教程:
Jenkov Java Concurrency Tutorial
本节介绍如何使用对象中的wait()
,notify()
和notifyAll()
方法。
如果你让我,我建议你阅读整篇(相对较短的)教程,你将从java并发中快速理解许多方面。