java - 如何在java中的 Action 监听器中启动/恢复和停止/暂停线程

标签 java multithreading swing

我正在用java编写一个简单的多线程练习。我需要做的就是制作一个带有两个按钮(“开始”和“结束”)的 JFrame。如果用户点击“开始”按钮,控制台将开始打印“打印”。如果单击“结束”,控制台将停止打印。再次单击“开始”将恢复打印。
这是我的代码(不相关部分未显示):

//import not shown

public class Example extends JFrame implements Runnable {
    private static boolean print, started;//print tells whether the thread should keep printing 
                                          //things out, started tells whether the thread has been 
                                          //started 
    private JButton start;//start button
    private JButton end;//end button
    private static Thread thr;//the thread that is going to do the printing
    //other fields not shown

    public Example(String title) {
        Container c = getContentPane();
        //set up the JFrame
        //...parts not shown
        start = new JButton("Start");
        end = new JButton("End");
        c.add(start);
        c.add(end);
        //add the actionListner for the buttons
        start.addActionListener(new ActionListener() {
         
            @Override
            public void actionPerformed(ActionEvent e) {
                if (started == false) {
                    thr.start();// if the thread has not been started, start the thread
                    started = true;
                }else{//otherwise waken the thread. This is to prevent IllegalThreadStateException.
                    thr.notify();
                }
                print = true;//should print things out
            }
        });
        end.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                
                if(started) {//This action won't pause the thread if its not yet started
                    try {
                        thr.wait();//pause the thread
                    } catch (InterruptedException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
                print = false;//should stop printing
            }
        });
        validate();
        setVisible(true);

    }

    @Override
    public void run() {//override run() method
        while (print) {
            System.out.println("Printing");//print out "Printing"
        }
    }

    public static void main(String[] args) {//main method
        Example ex = new Example("My Frame");//instantiate the frame
        thr = new Thread(ex);//make a new thread;
        started = false;//the thread has not been started, so set started to false;
    }
}
但是,一旦单击开始按钮,控制台就永远不会停止打印。我不断收到 IllegalMonitorStateException。是什么导致了这个问题?
我找不到错误,因为所有部分在逻辑上似乎都是正确的。任何帮助将不胜感激。

最佳答案

提供的代码不会打印任何内容。它也不会编译,你需要修复 private static Thread;private static Thread thr; .
无论如何,这可以工作与否,取决于代码缺乏任何同步。这意味着在一个线程中对变量所做的更改不需要在另一个线程中可见。如果您将单个变量设置为 false最初,然后将其设置为 true在一个线程中,第二个线程仍然可以看到它的缓存值 false .
尝试制作您的 boolean变量 volatile看看它是否有效,但真正的答案是阅读线程同步 e.g. in the Java Tutorial

关于java - 如何在java中的 Action 监听器中启动/恢复和停止/暂停线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63210268/

相关文章:

java - 线程安全的日期解析器

java - Vert.x - Verticle 和 Services 之间的差异

java - 使用括号的通用转换

c# - 如何使用 ConcurrentQueue<T> 进行线程处理

java - 不使用JDialog如何使用JDialog

java - 如何在 Android DatePicker 中禁用以前的日期?

java - invokeAll() 是 java 7 中的阻塞调用

javascript - promise 导致崩溃的网络 worker

java - JTable 在未提交时从单元格获取值

java - 用Java swing画一个简单的圆不起作用