JUC练习17——锁
2022/2/3 6:13:32
本文主要是介绍JUC练习17——锁,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一,公平锁和非公平锁
公平锁:先来先执行,不能插队
非公平锁:可以插队,默认是非公平锁
public ReentrantLock() { sync = new NonfairSync(); } public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
二,可重入锁(递归锁)
拿到外层的锁就会自动获取里面的锁
代码示例:
/** * 由于synchronized 是可重入锁,所以call的锁和sms的锁是同时拿到的 * 因此在A线程执行完sms方法时,B线程是无法执行sms方法的,需要等到A线程一起释放锁 */ public static void main(String[] args) { Phones phone = new Phones(); new Thread(()-> { phone.call(); },"A").start(); new Thread(()-> { phone.sms(); },"B").start(); } class Phones { public synchronized void call() { sms(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+": call"); } public synchronized void sms() { System.out.println(Thread.currentThread().getName()+":sms"); } }
执行结果
A:sms
A: call
B:sms
三,自旋转锁
会不断的去尝试,直到成功为止,会使用到while循环
@HotSpotIntrinsicCandidate public final int getAndAddInt(Object o, long offset, int delta) { int v; do { v = getIntVolatile(o, offset); } while (!weakCompareAndSetInt(o, offset, v, v + delta)); return v; }
自定义自旋锁
import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; public class MyLock { AtomicReference<Thread> atomicReference = new AtomicReference<>(); public void lock() { Thread thread = Thread.currentThread(); System.out.println(thread.getName()+"尝试获取锁"); //将当前的线程和null进行比较,不满足则一直循环等待 while (!atomicReference.compareAndSet(null,thread)) { } System.out.println(thread.getName()+"成功获取锁"); } public void unlock() { Thread thread = Thread.currentThread(); System.out.println(thread.getName()+"解锁"); //将当前的线程和null进行比较,不满足则一直循环等待 atomicReference.compareAndSet(thread,null); } public static void main(String[] args) { MyLock myLock = new MyLock(); new Thread(()-> { try { myLock.lock(); TimeUnit.SECONDS.sleep(1); System.out.println("线程A执行操作"); } catch (Exception e) { e.printStackTrace(); }finally { myLock.unlock(); } },"A").start(); new Thread(()-> { try { TimeUnit.SECONDS.sleep(2); myLock.lock(); System.out.println("线程B执行操作"); } catch (Exception e) { e.printStackTrace(); }finally { myLock.unlock(); } },"B").start(); } }
测试结果:线程A先得到锁,线程B想要执行必须等线程A释放锁才可以执行
A尝试获取锁
A成功获取锁
线程A执行操作
A解锁
B尝试获取锁
B成功获取锁
线程B执行操作
B解锁
四,如何排查死锁
这篇关于JUC练习17——锁的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享