线程同步 可以保证资源共享操作的正确性,但是过度的设计,会导致程序死锁。死锁指的是有两个线程都在等待着对方完成释放资源,一个不释放,另外一个也不释放,一直僵持着,从而造成了程序的停滞。
ResourceA.java
package com.haicoder.net.thread.deadlock;
public class ResourceA {
public void getResourceA(){
System.out.println("获取资源A");
}
public void dealResourceA(){
System.out.println("需要资源 B 处理资源A");
}
}
ResourceB.java
package com.haicoder.net.thread.deadlock;
public class ResourceB {
public void getResourceB(){
System.out.println("获取资源B");
}
public void dealResourceB(){
System.out.println("需要资源 A ,来处理资源B");
}
}
ThreadDeadLock.java
package com.haicoder.net.thread.deadlock;
public class ThreadDeadLock implements Runnable {
private static ResourceA resourceA = new ResourceA();
private static ResourceB resourceB = new ResourceB();
private boolean flag = false;
@Override
public void run() {
if (flag) {
synchronized (resourceA) { //锁住了资源 A
resourceA.getResourceA();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resourceB) {
resourceA.dealResourceA();
}
}
} else {
synchronized (resourceB) { //锁住了资源 B
resourceB.getResourceB();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resourceA) {
resourceB.dealResourceB();
}
}
}
}
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
ThreadDeadLock t1 = new ThreadDeadLock();
ThreadDeadLock t2 = new ThreadDeadLock();
t1.flag = true;
t2.flag = false;
new Thread(t1).start();
new Thread(t2).start();
}
}
两个线程都在彼此等待彼此完成释放资源给自己使用,这样就产生了死锁。程序一直在执行中,占用 CPU 资源。
在平时编写代码过程中,用到同步到场景是很多的,但是我们要合理的使用同步,过多的同步有可能会产生死锁。我们可以在使用同步的时候保证同步的资源的顺序性,比如线程 1 过来同步线程的时候是资源 A,资源 B,那我们是不是可以考虑在线程 2 过来同步资源的时候也是资源 A 和资源 B 的顺序呢?这样就可以避免发生死锁了。