Java简单锁机制,synchronized死锁并解决
2016-11-17 14:11
267 查看
下面例子有一定概率deadLock
解决方案:
import com.sun.org.apache.regexp.internal.RE; /** * Created by butter on 16/11/15. */ class Resource{ private String name; private int resource; public Resource(String name, int resource) { this.name = name; this.resource = resource; } synchronized void doSome(){ System.out.println("doing some thing"); resource++; } synchronized void cooperate(Resource resource){ System.out.println("cooperating"); resource.doSome(); } } /** * * 两个Resource对象 r1, r2 * 两个线程t1, t2 * t1调用cooperate(r2)时获取r1的锁,如果此时此刻t2正在调用cooperate(r1)将获取r2的锁 * 这时,t1.cooperate(r2)执行r2.doSome(),将申请获取r2的锁,r2锁被t2获取,所以等待 * 并且,t2.cooperate(r1)执行r1.doSome(),将申请获取r1的锁,r1的锁被t1获取,继续等待, * * 结果就是t1 等 t2 的锁 t2 等 t1 的锁,互相等待对方的锁,造成死锁 */ public class Demo_deadLock { public static void main(String[] args) { Resource r1 = new Resource("1", 1); Resource r2 = new Resource("2", 2); // 循环次数多一些,为了得到上述情况 Thread thread1 = new Thread(()->{ for (int i = 0; i < 100; i++) { r1.doSome(); r1.cooperate(r2); } }); System.out.println("t1 over"); Thread thread2 = new Thread(()->{ for (int i = 0; i < 100; i++) { r2.doSome(); r2.cooperate(r1); } }); thread1.start(); thread2.start(); System.out.println("t2 over"); } }
解决方案:
import java.util.concurrent.locks.ReentrantLock; /** * Created by butter on 16-11-17. */ /** * * 每次线程尝试获取lock,获取不到,释放已有lock,解决deadlock * */ class Resource1{ private String name; private int resource; private ReentrantLock lock = new ReentrantLock(); //Lock接口 public Resource1(String name, int resource) { this.name = name; this.resource = resource; } void doSome(){ System.out.println(Thread.currentThread().getName() + " doing some thing: " + name+ " " + resource); resource++; } void cooperate(Resource1 resource){ while(true) { try { if (lockMeAnd(resource)) { System.out.println(Thread.currentThread().getName() + " r1 & r2 has been Locked"); System.out.println(Thread.currentThread().getName() + " cooperating"); resource.doSome(); break; } else { System.out.println( Thread.currentThread().getName() +" can't lock r1&r2"); } }finally { unLockMeAnd(resource); System.out.println(Thread.currentThread().getName() + " r1 & r2 has been unLocked"); } } } private boolean lockMeAnd(Resource1 res){ /*尝试获取锁, 获取不到->不阻塞*/ return this.lock.tryLock() && res.lock.tryLock(); } private void unLockMeAnd(Resource1 res){ if(this.lock.isHeldByCurrentThread()){ this.lock.unlock(); } if(res.lock.isHeldByCurrentThread()){ res.lock.unlock(); } } } public class Demo_noDeadLock { public static void main(String[] args) { Resource1 r1 = new Resource1("a", 1); Resource1 r2 = new Resource1("b", 2); Thread t1 = new Thread(()->{ for (int i = 0; i < 10; i++) { r1.cooperate(r2); } }); Thread t2 = new Thread(()->{ for (int i = 0; i < 10; i++) { r2.cooperate(r1); } }); t1.start(); t2.start(); } }
相关文章推荐
- 简单的Java1.4版synchronized多线程的死锁演示
- Java基础系列:(3)反射机制的简单总结
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- 带按钮监听机制的简单java GUI
- 双按钮双事件监听机制的简单java GUI
- java程序运行机制的简单梳理
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java中的异常处理机制的简单原理和应用以及连接池理解
- eclipse:java.lang.OutOfMemoryError: PermGen space 最简单的解决方式
- java synchronized死锁的好例子
- Java中的Synchronized,有时候没有那么简单
- java synchronized 简单示例
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- 【Java线程】锁机制:synchronized、Lock、Condition
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java的SPI机制与简单的示例
- 【JAVA 工具】jstack简单使用,定位死循环、线程阻塞、死锁等问题
- 浅谈Java回调机制的简单理解
- 【Java线程】锁机制:synchronized、Lock、Condition
- 2、Java的垃圾回收机制的简单理解