Java线程同步的几种方式

Java线程同步的几种方式

1.使用synchronized关键字
 它的工作是对同步的代码加锁,使得每一次只能有一个线程进入同步块,从而保证线程间的安全性。
 synchronized关键字的用法:
(1)同步方法
 即有synchronized修饰的方法,由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。代码如:public synchronized void save(){}。
 synchronized也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。
(2)同步代码块
 即有synchronized修饰的代码块,被该关键字修饰的语句块会自动被加上内置锁,从而实现同步。代码如:synchronized(Object){}
 通常没有必要同步整个方法,只用synchronized同步关键代码块即可。

2.使用重入锁ReentrantLock
 重入锁使用java.util.concurrent.locks.ReentrantLock类来实现
 ReentrantLock是可重入、互斥、实现了Lock接口的锁,这种锁可以反复进入。

 常用方法有:
 (1)Lock():获得锁,如果锁已经被占用,则等待
 (2)LockInterruptibly():获得锁,但优先响应中断
 (3)tryLock():尝试获得锁,如果成功,则返回true,失败则返回false。该方法不等待,立即返回。
 (4)tryLock(long time, TimeUnit unit):在给定时间内尝试获得锁
 (5)unlock():释放锁

 ReentrantLock()还有一个可以构造公平锁的构造方法,但会大幅降低程序运行效率。
 在重入锁的实现中,主要包含三个要素:
 (1)原子状态。原子状态使用CAS操作来存储当前锁的状态,判断锁是否已经被别的线程持有了。
 (2)等待队列。所有没有请求到锁的线程,会进入等待队列进行等待。待有线程释放锁后,系统能从等待队列中唤醒一个线程,继续工作。
 (3)阻塞原语park()和unpark(),用来挂起和恢复线程,没有得到锁的线程将会被挂起。

3.使用局部变量ThreadLocal
 如果使用ThreadLocal管理变量,则每一个使用该变量的线程得到的都只是该变量的副本,副本之间相互独立,这样每一个线程都可以修改自己的变量副本,而不会对其他线程产生影响。

 ThreadLocal类的常用方法:
 (1)ThreadLocal():创建一个线程本地变量
 (2)get():返回此线程局部变量的当前线程副本中的值
 (3)initialValue():返回此线程局部变量的当前线程的“初始值”
 (4)set(T value):将此线程局部变量的当前线程副本中的值设置为value

 ThreadLocal的实现原理:
 利用ThreadLocalMap,它是定义在Thread内部的成员。设置到ThreadLocal中的数据,正是写入了这个Map,其中key为ThreadLocal当前对象,value是我们需要的值。ThreadLocalMap类似于WeakHashMap,它的实现使用了弱引用,Java虚拟机在垃圾回收时,如果发现弱引用,会立即回收。ThreadLocalMao内部由一系列Entry构成,每一个Entry都是WeakReference。
 在set时,首先获得当前线程对象,然后通过getMap()方法拿到线程的ThreadLocalMap,并将值存入ThreadLocalMap中。
 get()时,先获得当前线程的ThreadLocalMap对象,然后通过将自己作为key取得内部的实际数据。

4.使用关键字volatile
 volatile关键字为域变量的访问提供了一种免锁机制
 当用volatile声明一个变量时,就等于告诉了虚拟机,这个变量极有可能会被某些程序或者线程修改,为了确保这个变量被修改后,应用程序范围内的所有线程都能够“看到”这个改动,虚拟机就会采取写特殊的手段,保持这个变量的可见性等特点。
 每次使用被volatile修饰的变量时,都会重新进行计算,而不是使用寄存器中的值.
 volatile不能替代锁,也无法保证一些复合操作的原子性(比如无法保证i++的原子操作),也不能用来修饰final类型的变量.

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

loser与你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值