美文网首页工作生活
Synchronized&&volatile 学习

Synchronized&&volatile 学习

作者: 咩咩籽 | 来源:发表于2019-07-01 15:53 被阅读0次

一般认为Synchronized锁定的是这段代码块,但事实上,Synchronized锁定的是当前对象。不仅如此Synchronized锁定的是heap内存中的这个对象而不是这个对象引用

一般我们不使用字符串常量来作为锁对象,因为这样会使得线程莫名的阻塞。看起来是两个字符串的引用但是他们指向的是同一段的内存。例如有个lib的jar包,我们看不到源码,但是它方法种锁定了“hello”这个字符串,我们在自己的代码中也锁定了“hello”,效果就很美妙,进程会一直等待。

关于线程安全:加synchronized关键字之后不一定能实现线程安全,具体还要看锁定的对象是否唯一。堆内存中的地址是否一样

锁定的对象有两种情况:①类的实例 ②类的字节码(.class)

synchronized关键字修饰普通方法等同于synchronized(this)

synchronize关键字修饰静态方法锁定的是类的.class文件,静态方法中synchronize锁定代码块,锁定的对象不能是类的实例,只能是类的.class文件。原理如同在静态方法中不能直接调用非静态方法。类的.class文件是唯一的,所以说synchronize修饰静态方法或者锁定的对象是类的.class文件的时候,在多线程中是可以实现线程安全的

1.同步方法和非同步方法是可以同时调用的

2.对业务写方法加锁,同时也要对业务读方法加锁,否则容易产生脏读问题

3.一个同步方法可以调用另一个同步方法,一个线程已经拥有某个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是说synchronized获得的锁是可重入的(这里是继承中有可能发生的情形,子类调用父类的同步方法

程序在执行过程中,如果出现异常,默认情况锁会被释放

锁定某对象o,如果o的属性发生改变,不影响锁的使用

但是如果o变成另外一个对象,则锁定的对象发生改变

应该避免将锁定对象的引用变成另外一个对象

1.业务逻辑中只有下面这句需要sync,这时不应该给整个方法上锁

2.采用细粒度的锁,可以是线程争用时间变短,从而提高效率


线程通信通常:一种是读取共享内存,还有一种就是线程之间互相通信。Java的线程采用的是读取共享内存。

volatile 关键字,使一个变量在多个线程间可见

A B线程都用到一个变量,java默认是A线程中保留一份copy,这样如果B线程修改了该变量,则A线程未必知道

使用volatile关键字,会让所有线程都会读到变量的修改值

使用volatile,将会强制所有线程都去堆内存中读取running的值

volatile并不能保证多个线程共同修改running变量时所带来的不一致问题,也就是说volatile不能替代synchronized

synchronize可以保证可见性和原子性,volatile只能保证可见性


++/--操作(其他操作)不是一个原子操作,所以在需要保证原子的++/--时可以通过上锁来解决问题,也可以通过

AtomXXX类来解决问题 

AtomXXX类本身方法都是原子性的,但不能保证多个方法连续调用是原子性

AtomicInteger count = new AtomicInteger(0); 

count.incrementAndGet(); //count++


使用门闩机制

使用Latch(门闩)替代wait notify来进行通知

好处是通信方式简单,同时也可以指定等待时间

使用await和countdown方法替代wait和notify

CountDownLatch不涉及锁定,当count的值为零时当前线程继续运行

当不涉及同步,只是涉及线程通信的时候,用synchronized + wait/notify就显得太重了

这时应该考虑countdownlatch/cyclicbarrier/semaphore

首先new一个门闩CountDownLatch latch = new CountDownLatch(1);

里面有一个参数,同时他有一个方法就是latch.await();

它会插在代码之间阻拦代码的执行。同时latch.countDown();

方法会减少门闩的数量当门闩的数量减少为0的时候,这时门会自动打开,这时候latch.await();会向下执行。

整个过程不涉及锁的机制,高效得实现了线程之间的通信。

@author mashibing


学习来自哔哩哔哩,马士兵老师高并发编程

相关文章

  • Synchronized&&volatile 学习

    一般认为Synchronized锁定的是这段代码块,但事实上,Synchronized锁定的是当前对象。不仅如此S...

  • 学习学习学习

    第三天了,连续三天,早上睁眼开始,看视频,做课件,连续作业,直到晚上十二点才睡觉。吃饭不规律,想起来就吃,感觉不饿...

  • 学习学习学习

    23岁的我,才真正明白,什么是学习,什么是努力,努力和不努力真的不同,就好比同样是一篇稿子,我用一周背下来,有的人...

  • 学习学习学习!

    妈妈总是让我学习,我只能用装当办法。 方法一: 方法二: 方法三: 方法四: ...

  • 学习学习学习

    001.今天看财富自由之路看了第二遍,而且看了一半,算是完成任务很开心。中间有想放弃的念头,坚持看完。眼睛痛,一直...

  • 学习学习学习

    马自达为什么坚持高压缩比自吸

  • 学习!学习!学习!

    学习的痛苦是暂时的 没有学到的痛苦是永恒的 因为学习而特别充实的一天 很踏实 ~~~~ 2015.11.28.阴天...

  • 学习!学习!学习!

    无数次想要去逃离,可这封闭的世界根本出不去。你没有什么可以抛弃、只能咬着牙带着面具微笑的活下去。 没有那个人、他也...

  • 学习学习学习!

    昨天和今天两个上午,都在学习新媒体运营,学习的过程中心里只有一个想法:这也太套路,太功利了吧。可真应了那句话...

  • 学习,学习,学习!

    近期学习重点有两个方面,一方面是把上一个阶段定下任务的几本书读完,并在读的过程中有输出和转化,让阅读和学习真正能有...

网友评论

    本文标题:Synchronized&&volatile 学习

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