java synchronized 死锁问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java synchronized 死锁问题相关的知识,希望对你有一定的参考价值。

public class DeadLock
public static void main(String[] args)
TestDeadLock dl1 = new TestDeadLock(false);
TestDeadLock dl2 = new TestDeadLock(true);
dl1.start();
dl2.start();




package Thread.Lock;

public class TestDeadLock extends Thread
static Object lock1 = new Object();
static Object lock2 = new Object();
public boolean flag ;
public TestDeadLock(boolean flag)
this.flag=flag;


public void run()
if(flag)
synchronized(lock1)
System.out.println("锁定lock1");
try
Thread.sleep(500);
catch (Exception e)
e.printStackTrace();


synchronized(lock2)
System.out.println("锁定lock2");


else
synchronized(lock2)
System.out.println("锁定lock2");
try
Thread.sleep(500);
catch (Exception e)
e.printStackTrace();

synchronized(lock1)
System.out.println("锁定lock1");





==========我说分割线======
如果我把
static Object lock1 = new Object();
static Object lock2 = new Object();
static修饰符去掉,就不在出现死锁现象。不知道为什么,望大神解释解释

参考技术A synchronized(obj) ... 称之为对obj加锁的同步代码块。 你可以这么理解,每一个java对象,都具有一个锁标记。而这个锁标记,同时只能分配给一个线程。 有synchronized(o),意思是只有获得o对象的锁标记之后,后面的代码块才会执行,否则会等待。 回到你的例子。x1和x2是两个不同的Xianc对象,但是,对于static的属性来说,任何Xianc对象都共享相同的值。因此,实际上,x1的o1属性和x2的o1属性指向同一个对象,而x1的o2属性和x2的o2属性也指向相同的对象。 也就是说,Xianc.o1和Xianc.o2表示两个对象,这两个对象被x1和x2作为静态属性共享。 然后,我们开始考虑锁标记的事情。程序中创建了两个线程t1和t2,并首先启动了t1线程。t1线程与x1绑定,此时执行的是flag == 0的代码块。 首先,遇到sync(o2),由于此时o2的锁标记还没有被分配,因此t1线程就能获得o2的锁标记,进入代码块。 进入代码块之后,接下来是sleep。由于t1线程sleep之后,释放了cpu,导致t2线程开始运行。由于t2线程与x2绑定,此时执行的是flag == 1的代码块。 这时,t2线程遇到sync(o1)。由于o1的锁标记没有被分配,因此t2线程就能获得o1的锁标记,进入代码块。同样的,进入代码块之后,t2也进入了sleep状态,释放了CPU。 过了一段时间,t1率先苏醒,并被执行。但是执行过程中,会遇到syn(o1)。此时,o1的锁标记被t2线程占据,t1无法获得锁标记,于是t1只能等待。 在等待过程中,t2也苏醒了。但是t2遇到了syn(o2),而此时o2的锁标记被t1占据,因此t2也只能等待。 于是,两个线程相互等待,就形成了死锁。 手打,楼主给分本回答被提问者和网友采纳

Java线程死锁

 Java多线程使用synchronized 锁时,可能会出现死锁;死锁会导致两个线程无限等待,致使程序异常。因此使用synchronized 关键字时注意死锁的问题。

 

笔者在第一次运行程序的时候属性 A=“a”、B=“a”,并没有引起死锁的问题;原因很简单,这时A 和 B的地址是一样的,synchronized 认为是同一个对象资源,不会对对象A 和 B同时加锁。

 

引起死锁的例子: 

public class DeadLock {

 private String A = "a";
private String B = "b";
@SuppressWarnings("static-access")
public void deadLock(){
Thread thread1 = new Thread(new Runnable(){
@Override
public void run() {
System.out.println("thread1-start");
synchronized (A) {
System.out.println("1" + A);
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (B){
System.out.println("2" + B);
}
}
System.out.println("thread1-end");
}
});
Thread thread2 = new Thread(new Runnable(){
@Override
public void run() {
System.out.println("thread2-start");
synchronized (B) {
System.out.println("3" + B);
synchronized (A){
System.out.println("4" + A);
}
}
System.out.println("thread2-end");
}
});
thread1.start();
thread2.start();
}
public static void main(String[] args){
    
new DeadLock().deadLock();
}
}

以上是关于java synchronized 死锁问题的主要内容,如果未能解决你的问题,请参考以下文章

Java线程死锁

ReentrantLock替换synchronized解决多线程并发死锁,Java

ReentrantLock替换synchronized解决多线程并发死锁,Java

JDK核心源码深入剖析(synchronized和ConcurrentHashMap)

Semaphore替换多线程synchronized解决并发环境死锁,Java

Java 中线程同步机制synchronized,互斥锁,死锁,释放锁的详解