Java中常见锁的分类

公平和非公平锁

公平锁:

多个线程按照申请的顺序来取锁,先来后到。

非公平锁:

不是按照来的顺序,上来就尝试占有锁,尝试失败再变成公平锁的方式申请锁,可能后申请的线程先获取锁,造成优先级反转和饥饿。
ReentrantLock默认非公平锁,可以通过传入boolean来改变。Synchronized也是非公平。

可重入锁(递归锁)

线程可以进入任何一个它已经拥有锁的同步代码块。一个线程获取到外层方法的锁,再进入该内层方法会自动获取锁,前提是二者锁同一对象。
ReentrantLock和synchronized非公平的可重入锁。
防止死锁。

synchronized(obj){
	synchronized(obj){
		//如果外层可以进,那么内层也可以进
	}
}

自旋锁

尝试获取锁时不会阻塞,而是采用循环的方式尝试获取锁,减少线程上下文的切换的消耗,缺点循环会消耗CPU。

//unsafe.getAndAddInt
//var2内存偏移
public final int getAndAddInt( Object var1, long var2 , int var4){
	int var5;
	do {
		var5 = this.getIntVolatile(var1,var2);
		//如果之前获取的var5在主内存中没被修改,则将新增写入,如果已经修改,则再次读取var5,直到成功写入内存
	}while( !this.compareAndSwapInt( var1, var2, var5, var5+var4));
	return var5;
}

自旋锁CAS详细介绍

https://blog.csdn.net/D1124615130/article/details/116159936?spm=1001.2014.3001.5501

读写锁

读-读共存
写-写互斥
写-读互斥
写操作:原子+独占 整个过程是一个完整体,中间不得分割

classMyCache{
	private volatile Map<String,Object> map = new HashMap<>();
	private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	
	public void put(String key,Object value){
		readWriteLock.writeLock().lock();
		try{
			System.out.println(Thread.currentThread().getName()+"写入"+key);
			try{Thread.sleep(300);}catch(InterruptedExceptione){e.printStackTrace();}
			map.put(key,value);
			System.out.println(Thread.currentThread().getName()+"写入完成");
		}catch(Exceptione){
			e.printStackTrace();
		}finally{
			readWriteLock.writeLock().unlock();
		}
	}


	public void get(String key){
		readWriteLock.readLock().lock();
		try{
			System.out.println(Thread.currentThread().getName()+"读");
			try{Thread.sleep(300);}catch(InterruptedExceptione){e.printStackTrace();}
			Objecto = map.get(key);
			System.out.println(Thread.currentThread().getName()+"读取完成"+o);
		}catch(Exceptione){
			e.printStackTrace();
		}finally{
			readWriteLock.readLock().unlock();
		}
	}
}

	/**
	*读可以共存
	*读写不能共存
	*写写不能共存
	*/
public class ReadWriteLockDemo{
	public static void main(String[] args){
		MyCache myCache = new MyCache();
		for(int I = 0 ; I < 5 ; i++){
			final int tmp = I ;
			new Thread( () -> {
				myCache.put(tmp+"",tmp+"");
			},String.valueOf(i)).start();
		}
		for(int i = 0 ; i < 5 ; i++){
			final int tmp = i;
			new Thread( () -> {
				myCache.get(tmp+"");
			},String.valueOf(i)).start();
		}
	}
}

运行结果
0写入0
0写入完成
1写入1
1写入完成
2写入2
2写入完成
3写入3
3写入完成
4写入4
4写入完成
0读
1读
2读
3读
4读
0读取完成0
3读取完成3
4读取完成4
1读取完成1
2读取完成2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值