多线程的学习 (六) 实现线程锁(ThreadLock)

本文详细介绍了线程锁的概念,包括自旋锁、阻塞锁、重入锁等类型,并探讨了lock与synchronized的区别。通过实际示例展示了如何在Java中实现线程安全的锁,包括检查锁的可重入性和正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 锁

1.1什么是锁

所谓的锁,肯定是不想别人去拿到的东西才会上锁。那什么是锁呢?
我们可以稍微定义一下:确保同一时间同一对象操作同一资源的方法。

1.1 都有哪些锁?

既然我们稍微的定义了一下锁,那我们平时在编程中的时候又有哪些锁呢。部分举例一下,如有不全可以补充:
自旋锁: 线程状态及上下文切换消耗系统资源,当访问共享资源的时间短,频繁上下文切换不值得。jvm实 现,使线程在没获得锁的时候,不被挂起,转而执行空循环,循环几次之后,如果还没能获得锁,则被挂起 阻塞锁:阻塞锁改变了线程的运行状态,让线程进入阻塞状态进行等待,当获得相应的信号(唤醒或者时间) 时,才可以进入线程的准备就绪状态,转为就绪状态的所有线程,通过竞争,进入运行状态 。
重入锁: 支持线程再次进入的锁,就跟我们有房间钥匙,可以多次进入房间类似。
读写锁: 两把锁,读锁跟写锁,写写互斥、读写互斥、读读共享 互斥锁: 上厕所,进门之后就把门关了,不让其他人进来。
悲观锁: 总是假设坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上 锁,这样别人想拿这个数据就会阻塞直到它拿到锁。
乐观锁: 每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别 人有没有去更新这个数据,可以使用版本号等机制。
公平锁: 大家都老老实实排队,对大家而言都很公平。
非公平锁: 一部分人排着队,但是新来的可能插队。
偏向锁: 偏向锁使用了一种等到竞争出现才释放锁的机制,所以当其他线程尝试竞争偏向锁时,持有偏向锁的 线程才会释放锁 独占锁:独占锁模式下,每次只能有一个线程能持有锁。
共享锁: 允许多个线程同时获取锁,并发访问共享资源。

1.2 如何使用锁

public static Lock lock = new ReentrantLock();

/**
 * 静态方法,直接对num计数器进行++操作。
 */
public static void inCreate() {
   
   

    lock.lock();
    num++;
    lock.unlock();
}

使用很简单,new一个锁,然后对需要枷锁的资源进行lock,在使用完成后需要unlock解锁操作就可以了。

1.3 lock与synchronized的区别

lock 获取锁与释放锁的过程,都需要程序员手动的控制 Lock用的是乐观锁方式。所谓乐观锁就是,每次不加 锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。乐观锁实现的机制就 是 CAS操作 synchronized托管给jvm执行 原始采用的是CPU悲观锁机制,即线程获得的是独占锁。独占锁意味 着其他线程只能依靠阻塞来等待线程释放锁。
PS: 在过去synchronized一直是一个重操作,会降低系统的性能,所以一般都会使用lock,但是lock使用又没有synchronized方便,需要枷锁,解锁。如果稍微有点逻辑错误就会使得系统发生异常。但是在jdk1.5之后,几乎每个版本都在对synchronized进行优化,特别是1.6版本之后synchronized已经得到了很好的优化,与lock几乎没有什么性能差异,更别说现在13都快出来啦!!13都快出来啦!!13都快出来啦!!

2 实现锁。

实现一个简单的锁,我们要做到最低的要求。

  1. 能枷锁,能解锁。
  2. 可重入。
/**
 * @ClassName MyLock
 * @Description TODO 实现一个锁
 * @Author CabbageDevil
 *
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值