16.各种锁
各种锁
1、公平锁,非公平锁
公平锁:非常公平,不能插队
非公平锁:非常不公平,可以插队(默认都是非公平)
//非公平锁
ReentrantLock reentrantLock = new ReentrantLock();
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
//公平锁
ReentrantLock reentrantLock = new ReentrantLock(true);
2、可重入锁
可重入锁(递归锁)
Synchronized版
public class SyncDemo {
public static void main(String[] args) {
new Thread(() -> {
Phone phone = new Phone();
phone.sms();
},"A" ).start();
new Thread(() -> {
Phone phone = new Phone();
phone.sms();
},"B" ).start();
}
}
class Phone {
public synchronized void sms() {
System.out.println(Thread.currentThread().getName() + " sms");
call();
}
public synchronized void call() {
System.out.println(Thread.currentThread().getName() + " call");
}
}
Lock版
public class LockDemo {
public static void main(String[] args) {
Phone1 phone = new Phone1();
new Thread(() -> {
phone.sms();
}, "A").start();
new Thread(() -> {
phone.sms();
}, "B").start();
}
}
//
class Phone1 {
ReentrantLock lock = new ReentrantLock();
public void sms() {
lock.lock();//lock和unlock必须成对出现,有加锁就必须有解锁,否则死锁
try {
System.out.println(Thread.currentThread().getName() + " sms");
call();//这里也有锁
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void call() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " call");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
3、自旋锁
自写自旋锁
/*
* 自定义自旋锁
* */
public class MyLock {
AtomicReference<Thread> reference = new AtomicReference<>();
//加锁
public void myLock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + " mylock");
while (!reference.compareAndSet(null, thread)) {
}
}
//解锁
public void myUnLock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + " myunlock");
reference.compareAndSet(thread, null);
}
}
测试
public class MyLockTest {
public static void main(String[] args) throws InterruptedException {
MyLock lock = new MyLock();
new Thread(()->{
lock.myLock();
try {
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.myUnLock();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);//保证A先获取到锁
new Thread(()->{
lock.myLock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.myUnLock();
}
},"B").start();
}
}
总结:A先拿到锁,执行完,解锁,B才能拿到锁
4、死锁
死锁代码
public class DeadLock implements Runnable {
private String a;
private String b;
public DeadLock(String a, String b) {
this.a = a;
this.b = b;
}
@Override
public void run() {
synchronized (a) {
System.out.println(Thread.currentThread().getName() + "持有锁" + a + ",要去获取锁" + b);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b) {
System.out.println(Thread.currentThread().getName() + "持有锁" + b + ",要去获取锁" + a);
}
}
}
}
测试
//程序会一直卡着,死锁
//T1持有锁lockA,要去获取锁lockB
//T2持有锁lockB,要去获取锁lockA
public class DeadLockTest {
public static void main(String[] args) {
new Thread(new DeadLock("lockA", "lockB"), "T1").start();
new Thread(new DeadLock("lockB", "lockA"), "T2").start();
}
}
解决问题
-
jps -l
定位进程号PS D:\tools\juc> jps -l 11168 sun.tools.jps.Jps 6784 org.jetbrains.idea.maven.server.RemoteMavenServer36 832 lock.deadlock.DeadLockTest 4316 4748 org.jetbrains.jps.cmdline.Launcher PS D:\tools\juc>
-
jstack 进程号
查看进程信息发现:互相持有对方的锁
"T2": at lock.deadlock.DeadLock.run(DeadLock.java:24) - waiting to lock <0x000000076b8db678> (a java.lang.String) - locked <0x000000076b8db6b0> (a java.lang.String) at java.lang.Thread.run(Thread.java:748) "T1": at lock.deadlock.DeadLock.run(DeadLock.java:24) - waiting to lock <0x000000076b8db6b0> (a java.lang.String) - locked <0x000000076b8db678> (a java.lang.String) at java.lang.Thread.run(Thread.java:748)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY