volatile、synchronize关键字,Lock类的定义与特性

volatile关键字

定义:对该变量禁止使用CPU缓存,而从主内存中读写
特性:
  1. 禁止编码优化(禁止指令重排序)
  2. 保证变量的线程可见性,即线程B对线程A的操作是可见的,即原则1 遵循happens-before原则
  3. 不会对线程阻塞,而只是对变量的"读或写"保证原子性,但不对"读并且写"保证原子性。可以理解为有两个锁:读锁和写锁,但不可同时读和写,见increase方法;故此时一写多读时可以保证数据一致。
    若要多写多读,synchronize关键字或Lock类
    volatile static int inc = 0;

    public static void main(String[] args) {
        Runnable runnable = ()->{
            increase();
        };
        ExecutorService executorService = Executors.newFixedThreadPool(20);
        for (int i = 0; i < 20; i++) {
            executorService.execute(runnable);
        }
        // 等待所有线程结束
        executorService.shutdown();
        System.out.println(inc);
    }

    private static /*synchronized*/ void increase() {
        for (int i = 0; i < 1000; i++) {
            // 如线程A执行至256次内存读到256,线程B已经执行完1000次写入内存1000,此时线程A第257次内存读到1000,继续剩下的743次循环
            inc++; // inc = inc + 1 读inc并且写inc
        }
    }

19418
Process finished with exit code 0

happens-befores原则:

定义:前一个操作的结果对后续操作是可见的

共8条原则
主要为

  1. 顺序性
  2. volatile原则
  3. 传递性
    ...
    Java并发编程实战
    java 8大happen-before原则超全面详解

synchronize关键字

定义:Java中互斥锁技术的实现
特性:
  1. 可修饰方法,代码块
class X {
  // 修饰非静态方法
  synchronized void foo() {
    // 临界区
  }
  // 修饰静态方法
  synchronized static void bar() {
    // 临界区
  }
  // 修饰代码块
  Object obj = new Object();
  void baz() {
    synchronized(obj) {// lock()
      // 临界区
    //unlock()
    }
  }
}
  1. 修饰static方法时,实际锁的是该类的.class对象;修饰非static方法时,锁的时该this对象
    注意:使用锁synchronized要注意以哪个对象为锁,和要保护的资源(临界区),在同一个锁下的临界区是保证原子性的
class obj {
  synchronized(obj.class) static void foo1(){}
  // obj.class是单例的
  synchronized(this) void foo2(){}
  // this是可以new出多个的
}
  1. wait()、notify()、notifyAll()只能在sychronized代码块中使用
sychronized(this){
  this.wait() // 此处释放的锁一定为this,即锁对象
  // 若锁对象为targer,则为target.wait()
}

wait():释放该互斥锁,同时该线程进入等待队列,使其他线程可以抢占该锁 sleep()使线程阻塞,不会释放锁
notify(): 随机通知等待队列中的一个线程,条件满足,可以执行wait()之后代码
使用notifyAll():通知队列中所有线程,条件满足

Lock接口

定义:Lock为concurrent.locks包下的一个接口,该locks包提供对线程锁操作的方法。
特性:

1.常用实现类:

        ReentrantLock lock = new ReentrantLock();   // 实现Lock接口
        ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();    // 实现ReadWriteLock,提供读锁或写锁
        readWriteLock.writeLock().lock();  // 读锁

2.常用方法:

        lock.lock();// 获得锁
        try{
            //处理任务
        }catch(Exception ex){
        }finally{
            lock.unlock();   // 释放锁
        }
        lock.tryLock(); // 尝试获得锁,得到true,得不到false,立即返回

悲观锁与乐观锁CAS机制

悲观锁

定义:总是假设最坏的情况,假设每次取数据后都认为数据会被其他线程修改,需要保证数据的强一致性。如sychronized关键字和ReentrantLock类,都是悲观锁。

乐观锁与CAS

定义:假设每次取得数据后,数据不会被其他线程修改。
CAS:全称compareAndSwap,望文生义,即比较与替换。
每次进行对数据写操作时进行一次CAS:
compare:比较工作内存中的值A1,是否与主内存中地址V中的值A2一致;
swap:若A1与A2一致,则修改地址V中的A2为B;若A1与A2不一致,则重新读取地址V中的值,再进行任务处理,称为回旋,该情况可能一直循环直到一致为止。

CAS下带来的ABA问题:
按时间顺序有以下任务:
线程1任务:读地址V,A值修改为B值
线程2任务:读地址V,A值修改为B值
线程3任务:读地址V,B值修改为A值
根据CAS原则,线程1执行后,线程2回旋,线程3执行,最终值为A
若此时线程2阻塞,则只执行1和3,线程2释放,根据CAS原则,执行完1和3后,线程2回旋判定A值一致,修改为B,最终值为B
解决方法:每次写数据时,加入版本号,判断A1与A2一致时,同时判断版本号是否一致
如concurrent包下的Atomic类,为乐观锁。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容