第一种情况: 多个线程共享同一资源,并且某一线程内又调度其他线程,让其他线程先运行。矛盾在于 A 线程 拿到资源锁运行中让线程B运行,线程B 运行需要资源锁。而锁在线程A 中,从而引起的互相等待。
线程A:
package cn.hncu.thread.deadLock.v1;
public class ThreadA implements Runnable{
private S s = null;
private Thread b=null;
public ThreadA(S s, Thread b) {
this.s = s;
this.b = b;
}
@Override
public void run() {
System.out.println("ThreadA begin......");
synchronized (s) {
System.out.println("ThreadA拿到对象锁,进入同步块....");
try {
b.join();//拿着锁,调用线程B 引起了死锁
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadA, a="+s.a);
}
}
}
线程B
package cn.hncu.thread.deadLock.v1;
public class ThreadB implements Runnable{
private S s = null;
public ThreadB(S s) {
super();
this.s = s;
}
@Override
public void run() {
System.out.println("ThreadB begin......");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadB 睡后继续运行....");
synchronized (s) {
s.a = 100;
System.out.println("ThreadB 已经完成对资源s.a的赋值,s.a="+s.a);
}
}
}
演示
package cn.hncu.thread.deadLock.v1;
public class Demo1 {
public static void main(String[] args) {
S s = new S();
Thread b = new Thread( new ThreadB(s) );
Thread a = new Thread( new ThreadA(s, b) );
b.start();
a.start();
}
}
class S{
public int a=0;
}
结果 线程一直运行(右边红色可以看出)
解决办法: 设计线程时,注意规范避免在一个线程内部调用其他的线程。
线程死锁的第二种情况:多个线程需要多个资源,可能会造成一个线程拿部分资源。从而造成互相等待的情况死锁。
解决办法: 把线程需要的多个资源封装成一个资源。一次拿够。
线程A,需要资源 s1.s2 先拿s1 再拿s2
package cn.hncu.thread.deadLock.v2;
public class ThreadA implements Runnable{
private S1 s1 = null;
private S2 s2 = null;
public ThreadA(S1 s1, S2 s2) {
this.s1 = s1;
this.s2 = s2;
}
@Override
public void run() {
System.out.println("ThreadA begin......");
synchronized (s1) {
System.out.println("ThreadA拿到对象锁1:"+s1.a);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadA睡醒,准备拿对象锁2...");
synchronized (s2) {
System.out.println("ThreadA手握对象锁1和锁2,进行工作..."+s2.a);
}
}
}
}
线程B 也需要资源 s1 s2 先拿s2 再拿s1
package cn.hncu.thread.deadLock.v2;
public class ThreadB implements Runnable{
private S1 s1 = null;
private S2 s2 = null;
public ThreadB(S1 s1, S2 s2) {
this.s1 = s1;
this.s2 = s2;
}
@Override
public void run() {
System.out.println("ThreadB begin......");
synchronized (s2) {
System.out.println("ThreadB拿到对象锁2:"+s2.a);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadB睡醒,准备拿对象锁1...");
synchronized (s1) {
System.out.println("ThreadB手握对象锁1和锁2,进行工作..."+s1.a);
}
}
}
}
演示代码
package cn.hncu.thread.deadLock.v2;
public class Demo2 {
public static void main(String[] args) {
S1 s1 = new S1();
S2 s2 = new S2();
Thread b = new Thread( new ThreadB(s1,s2) );
Thread a = new Thread( new ThreadA(s1, s2) );
b.start();
a.start();
}
}
class S1{
public int a=1;
}
class S2{
public int a=2;
}
结果
然后互相等待死锁。