背景: 造成线程死锁的条件中,有一个就是多个线程对多个资源访问的时候没有按照顺序访问造成的。这边博文讲解解决方案的原理。
多个线程对多个资源访问时,我们可以引入Lock机制,利用Lock的tryLock和Lock.unLock方法就可以解决死锁的问题。
-
示例代码:
public class TryLock { private static Lock obj1 = new ReentrantLock(); // 代表对象1 private static Lock obj2 = new ReentrantLock(); // 代表对象2 private static void methodForMainThread() { String threadName = Thread.currentThread().getName(); Random random = new Random(); while(true) { if (obj2.tryLock()) { System.out.println(threadName + ": get obj2"); try{ if (obj1.tryLock()) { try{ System.out.println(threadName + ": get obj1"); break; }finally { obj1.unlock(); } } }finally { obj2.unlock(); } } try { Thread.sleep(random.nextInt(3)); } catch (InterruptedException e) { e.printStackTrace(); } } } private static void methodForChildThread() { String threadName = Thread.currentThread().getName(); Random random = new Random(); while(true) { if (obj1.tryLock()) { System.out.println(threadName + ": get obj1"); try{ if (obj2.tryLock()) { try{ System.out.println(threadName + ": get obj2"); break; }finally { obj2.unlock(); } } }finally { obj1.unlock(); } } try { Thread.sleep(random.nextInt(3)); } catch (InterruptedException e) { e.printStackTrace(); } } } static class FruitThread extends Thread { @Override public void run() { super.run(); methodForChildThread(); } } public static void main(String[] args) { Thread.currentThread().setName("主线程"); FruitThread fruitThread = new FruitThread(); fruitThread.start(); methodForMainThread(); } }
-
运行结果:
总结: 当遇到多个线程对多个资源访问,而且没有按照顺序访问时,这个时候引入Lock机制也是可以解决死锁的问题的。