Question

I am facing a problem which two threads are accessing shared variables without the ability to the see last changes.

I have a GUI thread that has a text box, a mouse click listener that once recorded a click, creates a new thread which injects values to the text box and when a second mouse click is invoked the last created thread will be stopped and a new one will be created that will inject values as well and so on..

public class SomeGuiClass{
    private static boolean isRunning = false;
    private static boolean canRun = true;
    private Thread thread;     

    public SomeGuiClass(){
        txt.addMouseListener(new MouseListener() {
            @Override
            public void mouseDoubleClick(MouseEvent arg0) { 
                if (isRunning){
                    // force the thread to stop running.
                    canRun = false;

                    // waits for the thread to stop his run.
                    while(isRunning);
                }

                thread = new Thread(new Runnable() {
                    @Override
                    public void run() { 
                        SomeGuiClass.isRunning = true;          

                        while(SomeGuiClass.canRun){
                            // Inject values to text box, using Display.asyncExec...

                            Thread.sleep(1000);
                        }

                        SomeGuiClass.isRunning = false;
                    }
                });

                SomeGuiClass.canRun = true;
                thread.start();
            }
        }
    }
}

The problem is that the GUI thread which reads isRunning cant see the last update that performed by the new thread, causing the while(isRunning) loop is running forever.

I tried using volatile and the same thing happens. It seems that what I am doing is logically right, only a lack of technical information about how the java memory model is missing.

Was it helpful?

Solution

Several observations :

  • You have to make both isRunning and canRun volatile to make it work

  • Since your other thread is only checking canRun every 1000 ms, you might still have long delay before processing your second call to mouseDoubleClick on GUI thread.

  • It is generally a very bad idea to make threads do busy-waiting with

    while(true){/*do nothing*/} loop. You should definitely use wait/notify mechanism instead to sync between threads

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top