Using boolean var for stopping threads

 ̄綄美尐妖づ 提交于 2019-12-07 17:29:52

问题


I have a Java book I'm learning from and in one of the examples, I saw something suspicious.

public class ThreadExample extends MIDlet {
    boolean threadsRunning = true; // Flag stopping the threads

    ThreadTest thr1;
    ThreadTest thr2;

    private class ThreadTest extends Thread {
        int loops;

        public ThreadTest(int waitingTime) {
            loops = waitTime;
        }

        public void run() {
            for (int i = 1; i <= loops; i++) {
                if (threadsRunning != true) { // here threadsRunning is tested
                    return;
                }

                try {
                    Thread.sleep(1000);
                } catch(InterruptedException e) {
                    System.out.println(e);
                }
            }
        }
    }

    public ThreadExample() {
        thr1 = new ThreadTest(2);
        thr2 = new ThreadTest(6);
    }

    public void startApp() throws MIDletStateChangeException {
        thr1.start();
        thr2.start();

        try {
            Thread.sleep(4000); // we wait 4 secs before stopping the threads - 
                                // this way one of the threads is supposed to finish by itself
        } catch(InterruptedException e) {
            System.out.println(e);
        }

        destroyApp();
    }

    public void destroyApp() {    
        threadsRunning = false;

        try {
            thr1.join();
            thr2.join();
        } catch(InterruptedException e) {
            System.out.println(e);
        }

        notifyDestroyed();
    }
}

As it is a MIDlet app, when it's started, the startApp method is executed. To keep it simple, the startApp method itself calls destroyApp and so the program destroys, stopping the threads and notifying the destruction.

The question is, is it safe to use this 'threadsRunning' variable and would its use inside both threads and in the destroyApp method cause any trouble at some point? Would 'volatile' keyword put in front of the declaration help to synchronize it?


回答1:


Setting a boolean value is atomic, and there is no "read then modify" logic in this example, so access to the variable doesn't need to be synchronised in this particular case.

However, the variable should at least be marked volatile.

Marking the variable volatile does not synchronise the threads' access to it; it makes sure that a thread doesn't miss another thread's update to the variable due to code optimisation or value caching. For example, without volatile, the code inside run() may read the threadsRunning value just once at the beginning, cache the value, and then use this cached value in the if statement every time, rather than reading the variable again from main memory. If the threadsRunning value gets changed by another thread, it might not get picked up.

In general, if you use a variable from multiple threads, and its access is not synchronised, you should mark it volatile.



来源:https://stackoverflow.com/questions/8063378/using-boolean-var-for-stopping-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!