【java】【高并发】自旋锁

一、什么是自旋锁?

自旋锁与互斥锁类似,通过“自旋”使当前线程不放弃CPU时间片,而是忙等待,直到锁的持有者释放了要获取的锁,所以可见“自旋锁”是一种非阻塞锁。

在叙述一下,阻塞锁,当一个线程A在获取到锁时,再有线程B试图获取锁时,那么线程B将会挂起(阻塞);而自旋锁是,当线程B试图获取锁时,如果获取不到,则处于自旋,不释放CPU资源,减少线程上下文切换开销,以便当线程A释放锁,直接运行。

二、自旋锁可能引起的问题:

1.过多占据CPU时间:如果锁的当前持有者长时间不释放该锁,那么等待者将长时间的占据cpu时间片,导致CPU资源的浪费,因此可以设定一个时间,当锁持有者超过这个时间不释放锁时,等待者会放弃CPU时间片阻塞;

2.死锁问题:试想一下,有一个线程连续两次试图获得自旋锁(比如在递归程序中),第一次这个线程获得了该锁,当第二次试图加锁的时候,检测到锁已被占用(其实是被自己占用),那么这时,线程会一直等待自己释放该锁,而不能继续执行,这样就引起了死锁。因此递归程序使用自旋锁应该遵循以下原则:递归程序决不能在持有自旋锁时调用它自己,也决不能在递归调用时试图获得相同的自旋锁。

三、JAVA中一种自旋锁的实现

package com.test.lock;
 
// 锁接口
public interface Lock {
    public void lock();
    
    public void unlock();
}
 
 
 
 
package com.test.lock;
 
import java.util.concurrent.atomic.AtomicBoolean;
 
/**
 * 测试-设置自旋锁,使用AtomicBoolean原子变量保存状态
 * 每次都使用getAndSet原子操作来判断锁状态并尝试获取锁
 * 缺点是getAndSet底层使用CAS来实现,一直在修改共享变量的值,会引发缓存一致性流量风暴
 * **/
public class TASLock implements Lock{
	private AtomicBoolean mutex = new AtomicBoolean(false);
	
	@Override
	public void lock() {
		// getAndSet方法会设置mutex变量为true,并返回mutex之前的值
		// 当mutex之前是false时才返回,表示获取锁
		// getAndSet方法是原子操作,mutex原子变量的改动对所有线程可见
		while(mutex.getAndSet(true)){
			
		}
	}
 
	@Override
	public void unlock() {
		mutex.set(false);
	}
 
	public String toString(){
		return "TASLock";
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值