【基础知识点】Synchronized、volatile与ThreadLocal区别及使用场景

1.Synchronized

Synchronized关键字保证了数据读写一致和可见性等问题,但是他是一种阻塞的线程控制方法,在关键字使用期间,所有其他线程不能使用此变量。(同步机制采用了“以时间换空间”的方式)

修饰一个类

class ClassName {
    public void method() {
       synchronized(ClassName.class) {
          // todo
       }
    }
 }

修饰一个方法

public synchronized void method()
{
   // todo
}

修饰一个代码块

public  void method()
{
   synchronized(this){
   ......
   }
}

修饰一个静态的方法

public synchronized static void method() {
   // todo
}

2.volatile

volatile如何实现可见性?

volatile变量每次被线程访问时,都强迫线程从主内存中重读该变量的最新值,而当该变量发生修改变化时,也会强迫线程将最新的值刷新回主内存中。这样一来,不同的线程都能及时的看到该变量的最新值。

但是volatile不能保证变量更改的原子性:

比 如number++,这个操作实际上是三个操作的集合(读取number,number加1,将新的值写回number),volatile只能保证每一 步的操作对所有线程是可见的,但是假如两个线程都需要执行number++,那么这一共6个操作集合,之间是可能会交叉执行的,那么最后导致number 的结果可能会不是所期望的。

所以对于number++这种非原子性操作,推荐用synchronized:

synchronizedthis{
     number++;   
}

3.synchronized和volatile比较

  1. volatile不需要同步操作,所以效率更高,不会阻塞线程,但是适用情况比较窄

  2. volatile读变量相当于加锁(即进入synchronized代码块),而写变量相当于解锁(退出synchronized代码块)

  3. synchronized既能保证共享变量可见性,也可以保证锁内操作的原子性;volatile只能保证可见性

4.ThreadLocal

ThreadLocal不是为了解决多线程访问共享变量,而是为每个线程创建一个单独的变量副本,提供了保持对象的方法和避免参数传递的复杂性。

顾名思义它是local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。(ThreadLocal采用了“以空间换时间”的方式)

参考资料

Java—线程多(工作内存)和内存模型(主内存)分析

Java多线程共享变量控制

使用synchronized的几种场景

synchronized底层实现原理及锁优化

synchronized锁定的到底是什么?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值