java 加锁_java多线程加锁的简单处理办法

当对数据修改时,如果两个线程同时去修改同一条数据,这样产生的结果就不是我们预期的结果。这时候就需要对修改操作进行加锁,让jvm里同一时刻只能有一个线程能够执行修改方法。

下面是一个未加锁的修改方法:

public void update(Entry entry){

dao.update(entry);

现在讨论下传统的加锁方法。我们知道每一个对象都隐含了一个锁,那就是对象本身。我们可以在方法体上加上同步字段synchronized

public synchronized void update(Entry entry){

dao.update(entry);

但如果方法里代码很多,那么加在方法上会锁住很多代码,我们可以使用同步块

public void update(Entry entry){

dobefore();

synchronized(this){

dao.update(entry);

doend();

而需要注意的是如果一个类中存在多个同步方法,那么所有同步方法的锁都是对象本身,也就是说当执行update的时候,别的线程不仅不能执行update连类中别的同步方法也不能使用。当然也可以使用一点技巧去规避这个问题,比如使用其他锁。

我们这篇博客说得不是上面的方法,而是另外一个位于java.util.concurrent.locks包下的ReentrantLock。

官方是这么说的:

一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

ReentrantLock 将由最近成功获得锁,并且还没有释放该锁的线程所拥有。当锁没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁并返回。如果当前线程已经拥有该锁,此方法将立即返回。可以使用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此情况是否发生。

此类的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间最长的线程。否则此锁将无法保证任何特定访问顺序。与采用默认设置(使用不公平锁)相比,使用公平锁的程序在许多线程访问时表现为很低的总体吞吐量(即速度很慢,常常极其慢),但是在获得锁和保证锁分配的均衡性时差异较小。不过要注意的是,公平锁不能保证线程调度的公平性。因此,使用公平锁的众多线程中的一员可能获得多倍的成功机会,这种情况发生在其他活动线程没有被处理并且目前并未持有锁时。还要注意的是,未定时的 tryLock 方法并没有使用公平设置。因为即使其他线程正在等待,只要该锁是可用的,此方法就可以获得成功。

使用它也很简单,你可以用如下结构来使用他:

class X {

private final ReentrantLock lock = new ReentrantLock();

// ...

public void m() {

lock.lock();  // block until condition holds

try {

// ... method body

} finally {

lock.unlock()

}

}

}

常用的方法就如上面所说的一样,lock和unlock

lock

public void lock()

获取锁。

如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为 1。

如果当前线程已经保持该锁,则将保持计数加 1,并且该方法立即返回。

如果该锁被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态,此时锁保持计数被设置为 1。

指定者:

接口 Lock 中的

lock

unlock

public void unlock()

试图释放此锁。

如果当前线程是此锁所有者,则将保持计数减 1。如果保持计数现在为 0,则释放该锁。如果当前线程不是此锁的持有者,则抛出 IllegalMonitorStateException。

指定者:

接口 Lock 中的

unlock

抛出:

IllegalMonitorStateException - 如果当前线程没有保持此锁

当然他还有别的很多方法,需要的话可以自己去看看。

对比synchronized这个锁是独立的,在一个类中多个同步块之间都是独立的,互不影响。最后说一句,因为同步块会让一段代码同一时刻只能有一个线程使用,多线程同时访问,一个使用其他都是等待状态,那么就存在一个性能问题。如果理解原子性,又那么牛X,利用原子性写出避免同步的免锁代码,什么synchronized啊,ReentrantLock啊,都是浮云。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值