线程学习记录04-volatile

2017-06-21  本文已影响0人  绝世懒人
public class RunThread extends Thread {

private boolean isRunning = true;

private void setRunning(boolean isRunning) {
    this.isRunning = isRunning;
}

@Override
public void run() {
    System.out.println("进入run方法.....");
    while (isRunning == true){
        //TODO 操作内容
    }
    System.out.println("线程停止....");
}


public static void main(String[] args) throws InterruptedException {
    RunThread runThread = new RunThread();
    runThread.start();
    Thread.sleep(2000);
    runThread.setRunning(false);
    System.out.println("isRunning已经被设置为false");
    System.out.println("isRunning : "+ runThread.isRunning);
  }
}

运行结果如下:

image.png

可以发现结果中isRunning 已经是被设置为false 了,但是却发现线程并没有停止。这是什么原因?

可以看如下图:

image.png image.png

runThread 本身只是一个变量而已,真正的线程是在start后才会开启。而在线程本身中的变量是存在于主内存中的,jdk5之后为了提高线程效率,每当新开一个线程都会去拷贝主内存的副本,放入每个线程独立的工作内存中,所以没有特殊情况,主内存中改变的值,并不会影响到线程。这也就解释了为什么isRunning 的值改变之后对线程没效果。
如果要解决这个变量共享的问题,可以使用volatile关键字进行修饰。

image.png

之后的运行结果:

image.png

这下,对主内存的变量进行的修改就可以被线程所共享到了,并按照代码预期的进行停止。

多线程示例:

public class RunningDemo implements Runnable {

private volatile boolean bo = true;

public void setBo(boolean bo) {
    this.bo = bo;
}

@Override
public void run() {
    while (bo == true) {

    }
    System.out.println("运行结束");
}

public static void main(String[] args) throws InterruptedException {
    RunningDemo runningDemo = new RunningDemo();

    Thread thread = new Thread(runningDemo);
    Thread thread2 = new Thread(runningDemo);
    thread.start();
    thread2.start();
    Thread.sleep(10); //注意一定要先休眠一小会,不然可能主线程把对象的值改了,线程还没创建。导致之后线程创建的值一开始就是false
    runningDemo.setBo(false);
    System.out.println(runningDemo.bo);
}
}
上一篇下一篇

猜你喜欢

热点阅读