Java锁之自旋锁

自旋锁是指定尝试获取锁的线程不会立即堵塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上线文切换的消耗,缺点就是循环会消耗 CPU。

手写一个自旋锁 

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
/**
 * 手写一个自旋锁
 * @author kavito
 *
 */
public class SpinLock {
	
	//原子引用类
	AtomicReference<Object> atomic=new AtomicReference<>();
	
	public void myLock(){
		System.out.println(Thread.currentThread().getName()+"\t进来");
		Thread thread=Thread.currentThread();
		while(!(atomic.compareAndSet(null, thread))){
			System.out.println(Thread.currentThread().getName()+"\t尝试加锁....");
		}
		System.out.println(Thread.currentThread().getName()+"\t加锁成功!");
	}
	
	public void myUnLock(){	
		Thread thread=Thread.currentThread();
		//释放锁
		atomic.compareAndSet(thread, null);
		System.out.println(Thread.currentThread().getName()+"\t解锁完毕!");	
	}
	
	public static void main(String[] args) {
		SpinLock spinLock=new SpinLock();
		new Thread(()->{
			spinLock.myLock();
			//睡眠2秒,让t2线程进去加锁
			try { TimeUnit.SECONDS.sleep(2); } catch (Exception e) { e.printStackTrace(); }
			spinLock.myUnLock();
		},"t1线程").start();		
		//先让t1线程加锁
		try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) { e.printStackTrace(); }
		new Thread(()->{
			spinLock.myLock();
			//模拟任务耗时
			try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) { e.printStackTrace(); }
			spinLock.myUnLock();	
		},"t2线程").start();
	}

}

运行效果: 

  

1、t1线程先进来,相对于原子引用对象atomic,预期值是null,实际atomic对象也是null,比较成功,atomic修改为t1线程对象thread,atomic.compareAndSet(null, thread)返回true,整体取反返回false,跳出循环,t1线程加锁成功。t1线程暂停2秒,t2进来了,由于t1线程还没释放锁,atomic里面实际的值还是t1线程对象,通过atomic.compareAndSet(null, thread)想讲t1对象更换为t2对象来获取锁,预期的值是null,实际值是t1线程对象,atomic.compareAndSet(null, thread)返回false,整体取反返回true,
进了while循环,一直循环尝试加锁,直到t1线程释放锁。

2、t1线程sleep时间到了,spinLockDemo.myUnlock()释放锁atomic.compareAndSet(thread, null),此时atomic的实际值是null,t1线程执行完毕。之前t2线程一直循环等待atomic的值为null,条件终于满足,t2线程atomic.compareAndSet(null, thread)加锁成功,返回true,取反为false,跳出while循环,spinLockDemo.myUnlock(),解锁,直到代码执行完毕!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值