简体   繁体   中英

Java can't resume thread after pause

First of all, I know there are several topics regarding my problem and I've read many... The best I found is from Java Docu ( link ) and I tried to adapt their solution.

But unfortunately my little game of life program isn't working as expected... When I pause the Thread who simulates the game (painting next generation to JPanel) it stops as expected, when I then try to resume, nothing happens (no exception, no chance to debug). What I of course can do is, stop the thread completly and create a new one which acts then as pause/resume... I don't want to use that work-around, because I want to understand the problem I've created and secondly I want to use the start thread differently ;)

So here's the code which produces the thread (I mainly worked with volatile and synchronized):

public class MainJFrame extends JFrame {

private static final long serialVersionUID = 1L;
private JPanelGrid jPanelGrid;
private volatile Thread simulation;
private volatile boolean threadSuspended;

private JMenuBar menuBar;
private JMenu main;

public MainJFrame() {
    jPanelGrid = new JPanelGrid(995, 770);
    getContentPane().add(jPanelGrid);
    initMenuBar();
    setJMenuBar(menuBar);
    pack();

    setTitle("Conrads Game of Life");
    setSize(1000, 800);
    setLocationRelativeTo(null); // displayed in the middle of the screen
    setResizable(false);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
}

public void startSimulation() {
    //jPanelGrid.reset();
    threadSuspended = false;
    simulation = new Thread() {
        @Override
        public void run() {
            Thread thisThread = Thread.currentThread();
            while (simulation == thisThread) { //this check is for the correct stop of the thread
                try {
                    Thread.sleep(50);
                    if(threadSuspended){ //this additional if is a performance tweak regarding Java Docu
                        synchronized (this) { //this part should be for the pause and resume feature
                            while (threadSuspended) {
                                wait();
                            }
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                jPanelGrid.paintNextGen(); //Do I access it incorrectly?
            }
        }
    };
    simulation.start();
}

public synchronized void stopSimulation() {
    simulation = null;
    notifyAll();
}

public synchronized void pauseResume(){
    threadSuspended = !threadSuspended;
    if(!threadSuspended){
        notifyAll();
    }
}

private void initMenuBar(){
    menuBar = new JMenuBar();
    main = new JMenu("Main");
    menuBar.add(main);

    JMenuItem pauseResume = new JMenuItem("Pause/Resume");
    pauseResume.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            pauseResume();
        }

    });
    main.add(pauseResume);

    JMenuItem start = new JMenuItem("Start");
    start.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            startSimulation();
        }

    });
    main.add(start);

    JMenuItem stop = new JMenuItem("Stop");
    stop.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            stopSimulation();
        }

    });
    main.add(stop);
}

}

Main problem

You are sharing the threadSuspended variable across different threads. You are protecting it by synchronized , but you are synchronizing on different objects.

synchronized (this) <-- here this is a Thread object, try using JFrame.this instead

public synchronized void pauseResume(){ <-- here you are synchronizing on a JFrame object


EDIT : Deleted section about double-checking, you are using volatile so post Java 5.0 this code should be ok I think. See https://en.wikipedia.org/wiki/Double-checked_locking for more information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM