java两种经典死锁例子,Lock发生死锁案列

第一种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{
                        System.out.println(Thread.currentThread().getName()+" get locka ing!");
                        Thread.sleep(500);
                        System.out.println(Thread.currentThread().getName()+" after sleep 500ms!");
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+" need lockb!Just waiting!");
                    synchronized (lockb){
                        System.out.println(Thread.currentThread().getName()+" get lockb ing!");
                    }
                }
            }
        },"thread1");

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lockb){
                    try{
                        System.out.println(Thread.currentThread().getName()+" get lockb ing!");
                        Thread.sleep(500);
                        System.out.println(Thread.currentThread().getName()+" after sleep 500ms!");
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+" need locka! Just waiting!");
                    synchronized (locka){
                        System.out.println(Thread.currentThread().getName()+" get locka ing!");
                    }
                }
            }
        },"thread2");

        thread1.start();
        thread2.start();
    }
}

执行main方法之后控制台打印内容如下:

thread1 get locka ing!
thread2 get lockb ing!
thread1 after sleep 500ms!
thread1 need lockb!Just waiting!
thread2 after sleep 500ms!
thread2 need locka! Just waiting!

thread1 need lockb!Just waiting!表明thread1线程进入死锁等待lockb释放。

thread2 need locka! Just waiting!  表明thread2线程进入死锁等待locka释放。 

第二种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外释放锁!");
        }
    }
}

    原文作者:java锁
    原文地址: https://blog.csdn.net/li396864285/article/details/51487637
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞