java死锁

来源:互联网 发布:git本地仓库 windows 编辑:程序博客网 时间:2024/06/14 06:53

今天公司项目当中代码中出现 了死锁,因为是第一次在项目中遇到,所以记录下来,也借着这个事情开始自己写博客的道路。

代码发生的情况简单模拟如下:

import java.util.HashMap;import java.util.Map;public class Match {public Map map=new HashMap<>();public synchronized void match1() {System.out.println(Thread.currentThread().getName()+"获取到方法锁");threadSleep(3000);synchronized(map) {System.out.println(Thread.currentThread().getName()+"获取到对象锁");}System.out.println(Thread.currentThread().getName()+"释放方法锁");}public void match2() {synchronized(map) {System.out.println(Thread.currentThread().getName()+"获取到对象锁");threadSleep(3000);match1();}}public void threadSleep(int sleepTime) {try {Thread.sleep(sleepTime);} catch (InterruptedException e) {}}}

然后测试类如下:

public class Test {public static void main(String[] args) {Match m =new Match();Thread t1=new Thread(new Runnable() {@Overridepublic void run() {m.match2();}},"t2");t1.start();m.match1();}}

一开始我是在线程里面新建了一个Match对象,然后调用match2方法,结果没有发生我想要的死锁 情况,后来通过问同事知道,原来synchronized作用在方法上的时候等于synchronized(this),只有该方法是静态方法或者synchronized(Match.class)才会对全部的对象都有效果。

然后在控制台输入jps和jstack可以发现有产生死锁并且明确指出了死锁的位置。



然后我通过用jdk1.5中的ReentrantLock对象的tryLock()方法来获取锁。如果不写参数的话,如果获取不到锁立即返回false

import java.util.HashMap;import java.util.Map;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.ReentrantLock;public class Match2 {public ReentrantLock  mapLock=new ReentrantLock();public Map map=new HashMap<>();public boolean lock() {try {return mapLock.tryLock(1000, TimeUnit.MILLISECONDS);} catch (InterruptedException e) {e.printStackTrace();}return false;}public void unlock() {mapLock.unlock();}public synchronized void match1() {System.out.println(Thread.currentThread().getName()+"获取到方法锁");threadSleep(3000);if(lock()){//在此处对map进行相关操作 System.out.println(Thread.currentThread().getName()+"获取到对象锁");unlock();}System.out.println(Thread.currentThread().getName()+"释放方法锁");}public void match2() {if(lock()) {//此处进行map的相关操作System.out.println(Thread.currentThread().getName()+"获取到对象锁");threadSleep(3000);match1();unlock();}}public void threadSleep(int sleepTime) {try {Thread.sleep(sleepTime);} catch (InterruptedException e) {}}}

除此之外也可以将Map转化concurrentHashMap因为这个是多线程安全的,而且在内部通过将整个map划分为零散的几个来进行加锁,有效的降低了锁的竞争。 这样效果会更好。  




原创粉丝点击