程序在调用wait()时停止;在java中

时间:2014-07-08 22:37:23

标签: java

我已经使用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++;
            }
        }   
    }
}

3 个答案:

答案 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()方法。

Thread Signal

如果你让我,我建议你阅读整篇(相对较短的)教程,你将从java并发中快速理解许多方面。