Java 为什么同步方法不能导致死锁
我使用synchronized来测试死锁,我发现synchronized不能通过在方法上添加它来导致死锁。代码如下:Java 为什么同步方法不能导致死锁,java,deadlock,synchronized,Java,Deadlock,Synchronized,我使用synchronized来测试死锁,我发现synchronized不能通过在方法上添加它来导致死锁。代码如下: public static void main(String[] args) { DeadLock t1 = new DeadLock(); DeadLock t2 = new DeadLock(); new Thread(() -> { t1.m1(); }).start(); new Thread(() ->
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
关键字阻止从多个同步块/方法对同一对象的并发访问
要造成死锁,两个线程应该要求另一个线程当前占用的资源
此代码将成功捕获死锁
公共类死锁{
公共静态void main(字符串[]args){
死锁t1=新死锁();
死锁t2=新死锁();
t1.其他组(t2);
t2.其他组(t1);
新线程(()->{
t1.m1();
}).start();
新线程(()->{
t2.m1();
}).start();
}
私人僵局;其他;
公共无效设置其他(死锁其他){
this.other=其他;
}
无效打印(字符串消息){
System.out.println(Thread.currentThread().getName()+msg);
}
同步的void m1(){
打印(“:m1开始”);
试一试{
时间单位。毫秒。睡眠(1);
}捕捉(中断异常e){
e、 printStackTrace();
}
打印(“:m1等待获取其他.m1”);
其他。m1();
}
}
发生这种情况是因为Java中的隐式对象监视器锁是可重入的。也就是说,如果线程在对象上持有隐式监视器锁,它将能够执行由该锁保护的任何代码段。当线程进入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();
}
}
然后在同一个死锁对象上调用这些方法。可以,但代码不执行它。您的两个线程使用两个不同的锁。这怎么会导致僵局?