美文网首页
Java线程 - Synchronized、Volatile

Java线程 - Synchronized、Volatile

作者: 52HzBoo | 来源:发表于2018-04-11 21:21 被阅读0次

    Synchronized特性

    • 原子性
    • 可见性

    JMM关于synchronized的两条规定:

    • 线程解锁前,必须把共享变量的最新值刷新到主内存中.
    • 线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值(注意:加锁与解锁需要是同一把锁).

    Synchronized实现可见性

    • 线程执行互斥代码的过程:
      1.获得互斥锁
      2.清空工作内存
      3.从主内存拷贝变量的最新副本到工作内存
      4.执行代码
      5.将更改后的共享变量的值刷新到主内存.
      6.释放互斥锁.
    可见性

    代码案例,实现非线程安全

    public class SynchronizedDemo {
        //共享变量
        private boolean ready = false;
        private int result = 0;
        private int number = 1;   
        //写操作 加上 synchronized 可保证线程原子性
        public void write(){
            ready = true;                        //1.1              
            number = 2;                         //1.2               
        }
        //读操作 加上 synchronized 可保证线程原子性
        public void read(){              
            if(ready){                           //2.1
                result = number*3;      //2.2
            }       
            System.out.println("result的值为:" + result);
        }
    
        //内部线程类
        private class ReadWriteThread extends Thread {
            //根据构造方法中传入的flag参数,确定线程执行读操作还是写操作
            private boolean flag;
            public ReadWriteThread(boolean flag){
                this.flag = flag;
            }
            @Override                                                                    
            public void run() {
                if(flag){
                    //构造方法中传入true,执行写操作
                    write();
                }else{
                    //构造方法中传入false,执行读操作
                    read();
                }
            }
        }
    
        public static void main(String[] args)  {
            SynchronizedDemo synDemo = new SynchronizedDemo();
            //启动线程执行写操作
            synDemo .new ReadWriteThread(true).start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //启动线程执行读操作
            synDemo.new ReadWriteThread(false).start();
        }
    }
    

    Volatile特性

    • 非原子性
    • 可见性

    Volatile使用场景

    要在多线程中安全的使用volatile变量,必须同时满足:

    1.对变量的写入操作不依赖于其当前值
    即改变后的volatile变量的值不能与它之前的值有关系.

    2.该变量没有包含在具有其他变量的不变式中.
    即不能存在通过volatile变量进行逻辑判断.

    相关文章

      网友评论

          本文标题:Java线程 - Synchronized、Volatile

          本文链接:https://www.haomeiwen.com/subject/huttkftx.html