如何解决为什么同步方法不能导致死锁
我使用synced测试了deadLock,并且发现synced无法通过在方法上添加deadLock导致deadLock。这是代码:
public static void main(String[] args) {
DeadLock t1 = new DeadLock();
DeadLock t2 = new DeadLock();
new Thread(() -> {
t1.m1();
}).start();
new Thread(() -> {
t2.m1();
}).start();
}
synchronized void m1() {
System.out.println(Thread.currentThread().getName() + ":m1 start");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printstacktrace();
}
System.out.println(Thread.currentThread().getName() + ":m1 waiting to get m2");
m2();
}
synchronized void m2() {
System.out.println(Thread.currentThread().getName() + ":m2 start");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printstacktrace();
}
System.out.println(Thread.currentThread().getName() + ":m2 waiting to get m1");
m1();
}
为什么同步方法不能导致死锁,它总是循环执行。
解决方法
您正在两个不同的实例上调用m1()
方法。 synchronized
关键字阻止从多个同步块/方法同时访问同一对象。 Read this
要引起死锁,两个线程应该请求另一个线程当前占用的资源。
此代码将成功陷入死锁!
public class DeadLock {
public static void main(String[] args) {
DeadLock t1 = new DeadLock();
DeadLock t2 = new DeadLock();
t1.setOther(t2);
t2.setOther(t1);
new Thread(() -> {
t1.m1();
}).start();
new Thread(() -> {
t2.m1();
}).start();
}
private DeadLock other;
public void setOther(DeadLock other) {
this.other = other;
}
void print(String msg) {
System.out.println(Thread.currentThread().getName() + msg);
}
synchronized void m1() {
print(":m1 start");
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
print(":m1 waiting to get other.m1");
other.m1();
}
}
,
之所以会这样,是因为Java中的隐式对象监视器锁定是 reentrant 。也就是说,如果线程在对象上持有隐式监视器锁,则它将能够执行该锁保护的任何代码段。当线程进入m1()
时,它可以输入m2()
(反之亦然),因为它已经拥有了锁。这将使广告无限地发生
要演示死锁,您必须使用两种不同的锁来保护这两种方法:
void m1() {
synchronized(obj1) {
System.out.println(Thread.currentThread().getName() + ":m1 start");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":m1 waiting to get m2");
m2();
}
}
void m2() {
synchronized(obj2) {
System.out.println(Thread.currentThread().getName() + ":m2 start");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":m2 waiting to get m1");
m1();
}
}
然后在相同 DeadLock
对象上调用这些方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。