使用boolean var来停止线程 [英] Using boolean var for stopping threads

查看:143
本文介绍了使用boolean var来停止线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一本我正在学习的Java书,在其中一个例子中,我看到了一些可疑的东西。

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();
    }
}

因为它是一个MIDlet应用程序,当它启动时,执行startApp方法。为了简单起见,startApp方法本身调用destroyApp,因此程序会销毁,停止线程并通知销毁。

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.

问题是,使用它是否安全'threadsRunning'变量并且在两个线程和destroyApp方法中使用它会在某些时候引起任何麻烦吗?声明前面的'volatile'关键字是否有助于同步它?

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?

推荐答案

设置布尔值是原子的,那里在这个例子中没有read then modify逻辑,因此在这种特殊情况下不需要同步对变量的访问。

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.

但是,变量应该在至少被标记为volatile。

However, the variable should at least be marked volatile.

标记变量volatile不会同步线程对它的访问;它确保线程不会因为代码优化或值缓存而错过另一个线程对变量的更新。例如,如果没有 volatile run()中的代码可能会读取 threadsRunning 在开头只调整一次值,缓存该值,然后每次在 if 语句中使用此缓存值,而不是再次从main中读取该变量记忆。如果 threadsRunning 值被另一个线程更改,则可能无法获取。

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.

一般来说,如果你使用来自多个线程的变量,并且它的访问不同步,你应该将它标记为volatile。

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

这篇关于使用boolean var来停止线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆