第一种synchronized方式死锁:
线程thread1先获取锁locka,然后在同步块里嵌套竞争锁lockb。
而线程thread2先获取锁lockb,然后在同步块里嵌套竞争锁locka
(此时已经被线程thread1拥有,而thread1在等待lockb,而lockb被thread2拥有,thread2在等待locka……无线循环)。
package com.app.test;
import org.apache.poi.util.SystemOutLogger;
/**
* Created by lirong5 on 2016/5/24.
*/
public class SyncDeadLock{
private static Object locka = new Object();
private static Object lockb = new Object();
public static void main(String[] args){
new SyncDeadLock().deadLock();
}
private void deadLock(){
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (locka){
try{
Thread.sleep(500);
System.out.println("locka ing!");
}catch(Exception e){
e.printStackTrace();
}
synchronized (lockb){
System.out.println("lockb ing!");
}
}
}
},"thread1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lockb){
try{
Thread.sleep(500);
System.out.println("lockb ing!");
}catch(Exception e){
e.printStackTrace();
}
synchronized (locka){
System.out.println("locka ing!");
}
}
}
},"thread2");
thread1.start();
thread2.start();
}
}
第二种concurrent包Lock错误使用,导致死锁:
lock.unlock();释放锁使用地方不规范,导致死锁不能正常释放!
package com.app.test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by lirong5 on 2016/5/24.
*/
public class LockDeadDemo {
public static void main(String[] args){
final DeadLockBean deadLockBean = new DeadLockBean();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
deadLockBean.productDeadLock();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
},"threadA");
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(310);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
deadLockBean.productDeadLock();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
},"threadB");
threadA.start();
threadB.start();
try {
System.out.println("main线程即将被join");
threadA.join();
threadB.join();
System.out.println("main线程从join中恢复");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static class DeadLockBean{
private Lock lock = new ReentrantLock();
public void productDeadLock() throws Throwable {
System.out.println(Thread.currentThread().getName() + " 进入了方法!");
lock.lock();
try{
System.out.println(Thread.currentThread().getName() + " 已经执行了!");
throw new Throwable("人为抛出异常Throwable");//关键代码行1,
//throw new Exception("人为抛出异常Exception");//关键代码行2,不会死锁,会在catch(Exception e中被捕获),嵌套lock.unlock()并释放
}catch(Exception e){
System.out.println(Thread.currentThread().getName()+" 发生异常catch!");
//lock.unlock();//关键代码行3,不建议在这里释放,假如发生【关键代码行1】会产生死锁
}finally{
System.out.println(Thread.currentThread().getName()+" 发生异常finally!");
lock.unlock();//关键代码行4,无论发生何种异常,均会释放锁。
}
//lock.unlock();//关键代码行5,假如发生不能捕获异常,将跳出方法体,不执行此处
System.out.println(Thread.currentThread().getName() + " tryCatch外释放锁!");
}
}
}