| 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(); //资源1 private static Object res1 = new Object(); //资源2 private static Object res2 = new Object(); public static void main(String[] args) { new Thread(() -> { boolean applySuccess = false; while (!applySuccess) { //向管理类,申请res1和res2,申请失败,重试 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 资源的锁"); //休眠 1秒 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 资源失败"); //申请失败休眠 200 毫秒后重试 try { Thread.sleep(200); } catch (Exception e) { e.printStackTrace(); } } } }).start(); new Thread(() -> { boolean applySuccess = false; while (!applySuccess) { //向管理类,申请res1和res2,申请失败,重试 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 资源的锁"); //休眠 1秒 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 资源失败"); //申请失败休眠 200 毫秒后重试 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); } } |