package constxiong.concurrency.a023;
import java.util.HashSet;
import java.util.Set;
/**
* 测试 一次性申请所有的资源,破坏 "占有且等待" 条件示例
* @author ConstXiong
* @date 2019-09-24 14:04:12
*/
public class TestBreakLockAndWait {
private final static Manger manager = new Manger();
private static Object res1 = new Object();
private static Object res2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
boolean applySuccess = false;
while (!applySuccess) {
applySuccess = manager.applyResources(res1, res2);
if (applySuccess) {
try {
System.out.println("线程:" + Thread.currentThread().getName() + " 申请 res1、res2 资源成功");
synchronized (res1) {
System.out.println("线程:" + Thread.currentThread().getName() + " 获取到 res1 资源的锁");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (res2) {
System.out.println("线程:" + Thread.currentThread().getName() + " 获取到 res2 资源的锁");
}
}
} finally {
manager.returnResources(res1, res2);
}
} else {
System.out.println("线程:" + Thread.currentThread().getName() + " 申请 res1、res2 资源失败");
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(() -> {
boolean applySuccess = false;
while (!applySuccess) {
applySuccess = manager.applyResources(res1, res2);
if (applySuccess) {
try {
System.out.println("线程:" + Thread.currentThread().getName() + " 申请 res1、res2 资源成功");
synchronized (res2) {
System.out.println("线程:" + Thread.currentThread().getName() + " 获取到 res1 资源的锁");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (res1) {
System.out.println("线程:" + Thread.currentThread().getName() + " 获取到 res2 资源的锁");
}
}
} finally {
manager.returnResources(res1, res2);
}
} else {
System.out.println("线程:" + Thread.currentThread().getName() + " 申请 res1、res2 资源失败");
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
}
/**
* 资源申请、归还管理类
* @author ConstXiong
* @date 2019-09-24 14:10:57
*/
class Manger {
private Set<Object> resources = new HashSet<Object>();
/**
* 申请资源
* @param res1
* @param res2
* @return
*/
synchronized boolean applyResources(Object res1, Object res2) {
if (resources.contains(res1) || resources.contains(res1)) {
return false;
} else {
resources.add(res1);
resources.add(res2);
return true;
}
}
/**
* 归还资源
* @param res1
* @param res2
*/
synchronized void returnResources(Object res1, Object res2) {
resources.remove(res1);
resources.remove(res2);
}
}