volatile 关键字

1、

/**
 * volatile 关键字,使一个变量在多个线程间可见
 * mian,t1线程都用到一个变量,java默认是T1线程中保留一份副本,这样如果main线程修改了该变量,
 * t1线程未必知道
 *
 * 使用volatile关键字,会让所有线程都会读到变量的修改值
 *
 * 在下面的代码中,running是存在于堆内存的t对象中
 * 当线程t1开始运行的时候,会把running值从内存中读到t1线程的工作区,在运行过程中直接使用这个副本,
 * 并不会每次都去读取堆内存,这样,当主线程修改running的值之后,t1线程感知不到,所以不会停止运行
 *
 *
 */
@Slf4j(topic = "test")
public class Demo {

    boolean running = true;
    List list = new ArrayList<>();


    /**
     * t1线程
     */
    public void test(){
        log.debug("test start...");
        boolean flag =running;
            while (running){

            }
        log.debug("test end...");
    }

    public static void main(String[] args) {
        Demo demo = new Demo();

        new Thread(demo :: test,"t1").start();

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        demo.running = false;
    }

}

代码执行结果

volatile 关键字_第1张图片

线程会一直 执行并不会停止,可见 demo.running = false; 并没有通知到子线程中

2、

/**
 * 比如说第一个线程加到100了,还没往上加,另外一个线程来了,把100拿过来执行方法,
 * 然后第一个线程继续加到101,第二个线程也加到101,他两往回写都是101,线程不会管你加到哪儿了,
 * 虽然说加了2但是实际上只加了1.
 * volatile并不能保证多个线程共同修改running变量时所带来的不一致问题,
 * 也就是说volatile不能替代synchronized或者说volatile保证不了原子性
 */
@Slf4j(topic = "test")
public class Demo {

    volatile int count = 0;

    public void test(){
        for (int i = 0; i < 10000; i++) {
            count ++;
        }
    }


    public static void main(String[] args) {
        Demo demo = new Demo();

        List threads = new ArrayList();

        //new 10個线程
        for (int i = 0; i < 10; i++) {
            threads.add(new Thread(demo::test, "t-" + i));
        }

        //遍历这个10个线程  依次启动
        threads.forEach((o)->o.start());

        //等待10个线程执行完
        threads.forEach((o)->{
            try {
                o.join();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        log.debug(demo.count+"");
    }

}

执行结果如下

17:39:48.478 [main] DEBUG test - 47677

可见volatile不能替代synchronized或者说volatile保证不了原子性

 

 

你可能感兴趣的:(java,java,并发编程)