concurrent 一

volatile 关键词 设置变量的可见性

线程A:

package demo;

public class ThreadDemo implements Runnable {
    private  boolean flag = false;

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public void run() {
        try {
            Thread.sleep(200);
        } catch (Exception e) {

        }
        flag = true;
        System.out.print("flag = " + isFlag());
    }
}

主线程:

package demo;

public class TestVolatile {

    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo();
        new Thread(threadDemo).start();
        while (true) {
            if (threadDemo.isFlag()) {
                System.out.println("-------------------");
                break;
            }
        }
    }

}

运行结果:


程序进入死循环。原因:

    CPU在读取数据值的时候会首先从缓存中读取数据。缓存:因为CPU的速度太快了内存跟不上,所以建立了缓冲区。

    A线程虽然已经将flag的值更改了但是CPU不知道,主线程进入死循环。代码部分为了演示的原因让A线程休眠了200ms。我们将这个200ms去掉就会发现线程有时会进入死循环,有时会成功的运行。这是线程在抢占CPU。在未休眠的情况下,如果A线程先抢占CPU跑完代码那么主线程就不会进入死循环,同理主线程先运行,先进入循环那么就会直接死循环。

加上volatile关键字:

private volatile boolean flag = false;

主线程代码不变。


    代码直接结束,原因:加上volatile后,对这个变量所有的读取操作都会直接读取内存,不会读取缓存。这就是我们所说的可见性。当时volatile只能解决可见性的问题,无法解决并发问题,并发问题还是要使用synchronized关键字。

    在代码执行的时候会有指令重排序的问题,这个时候使用volatile修饰的变量,不会有指令重排序的情况发生。

ThreadLocal:SimpleDateFormat是并发不安全的 使用ThreadLocal就可以在并发的环境下安全了

package demo.local;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class LocalThread {
    private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    public String format(Date date) {
        return df.get().format(date);
    }

    public Date parse(String str) throws ParseException {
        return df.get().parse(str);
    }

}
ThreadLocal是为每一个线程拷贝了一份变量,这个变量是线程独有的,所以不会有线程安全的问题。

也没写什么就写了一点volatile和ThreadLocal用法和好处。

努力吧,皮卡丘。



猜你喜欢

转载自blog.csdn.net/yidan7063/article/details/80281074