JAVA多线程高并发之ReentrantLock讲解公平锁

JAVA中多线程高并发场景下保证线程安全通常都会考虑加锁。但是在特殊场景下我们也可以采用java.util.concurrent包提供的线程安全的对象,避免加锁从而达到高效的目的。

但是,这些线程安全的对象仅仅指的是针对于原子性操作是线程安全的,如果多个方法同时调用无法保证线程安全,只能考虑加锁。这里我们举个列子:假设我们在多线程高并发场景下使用java.util.concurrent.ConcurrentLinkedQueue这个对象来获取队列中的元素,可以直接调用poll()方法,不用加锁也可以保证线程安全,假如我们在获取的时候需要先判断队列是否为空然后获取,也就是先调用isEmpty()方法、接着调用poll()方法,这种情况就无法保证线程安全,因为这里是两步操作,无法保证原子性。

ReentrantLock也是多线程并发时候加锁一种方式,通常会用来和synchronized做比较。我简单整理一下如下:

1、从使用方法角度对比

  1. ReentrantLock必须手动释放锁,synchronized不用考虑(发生异常自动释放锁)
  2. ReentrantLock可以尝试锁定 trylock
  3. ReentrantLock还可以调用lockInterruptibly方法,可以对线程interrupt方法做成响应
  4. ReentrantLock可以指定公平锁Lock lock = new ReentrantLock(true)

2、从性能角度对比

  1. JDK1.5以前synchronized性能略低于ReentrantLock,包含JDK1.5版本
  2. JDK1.5以后Java虚拟机对synchronized做了很多优化,增加了偏向锁、轻量级锁(多数情况下是自旋锁)、重量级锁等细节。性能和ReentrantLock差不多。

我们来分析ReentrantLock 指定公平锁Lock lock = new ReentrantLock(true)

package com.reentranlock;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ReentrantLock可以指定公平锁Lock lock = new ReentrantLock(true);
 * 
 * @author 小辉哥/小辉GE
 * <p>
 * 2019年8月10日 下午15:30:00
 */
public class ReentrFairlock {
	Lock fairLock = new ReentrantLock(true);

	public void fairLock(){
		for (int i = 0; i < 20; i++) {
			try {
				fairLock.lock();
				System.out.println("线程" + Thread.currentThread().getName() + "获得锁");
			} finally {
				fairLock.unlock();
			}
		}
	}
	
	public static void main(String[] args) {
		ReentrFairlock reentrLock = new ReentrFairlock();
		//公平锁
		List<Thread> threads = new ArrayList<Thread>();
		for (int i = 0; i < 5; i++) {
			threads.add(new Thread(reentrLock::fairLock, "thread--- " + i));
		}
		threads.forEach((o) -> o.start());

	}
}

测试输出结果如下:

结果分析:

我们可以很直观看出公平锁定义后,每个线程都是轮流获得锁执行方法。

以上代码仅供参考,如有不当之处,欢迎指出!!!

更多干货,欢迎大家关注和联系我。期待和大家一起更好的交流、探讨技术!!!

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值