java死锁的一个例子

来源:互联网 发布:我要开店淘宝网 编辑:程序博客网 时间:2024/04/29 06:24

java出现死锁的一个例子。

场景很简单,就是吃饭需要用到刀和叉,拿到刀子的就可以去那叉子,拿到叉子的人就可以去拿刀子,都拿不到就等待。都拿到的话就去吃饭,休息之后释放刀子和叉子

所以这种情况很可能会出现 a拿到刀子等着叉子,b拿到叉子等着刀子。然后谁都无法继续下一步,就死了。

类似的就是线程a得到某一个锁a,然后等着另一个锁b,但是此时线程b得到锁b,等着锁a,这样就死锁了。好了,下面看代码:

/**

 * 拿工具

 */

public class Wares {
    /**
     * 餐刀, 1空闲,2使用中
     */
    private static int knife = 1;

    /**
     * 叉子, 1空闲,2使用中
     */
    private static int fork = 1;

    /**
     * 还
     */
    public static void returnWares() {
        freeFork();
        freeKnife();
    }

    /**
     * 用叉
     */
    public synchronized static boolean useFork() {
        if (fork == 1) {
            Wares.fork = 2;
            return true;
        }
        
        return false;
    }

    /**
     * 用刀
     */
    public synchronized static boolean useKnife() {
        if (knife == 1) {
            Wares.knife = 2;
            return true;
        }

        return false;
    }

    private static void freeFork() {
        Wares.fork = 1;
    }

    private static void freeKnife() {
        Wares.knife = 1;
    }

}


人吃东西等一系列行为:

public class Man extends Thread {

    private String name;

    Man(String name, long firstTime) {
        this.name = name;
        this.firstTime = firstTime;
    }

    /**
     * 获取餐具时间
     */
    private static final long getTime = 800;
    
    /**
     * 第一次拿的时候等待时间
     */
    private long firstTime;;

    /**
     * 归还餐具使用时间
     */
    private static final long returnTime = 100;

    public void run() {
        while (true) {
            eat();
            rest();
            done();
        }
    }

    /**
     * 方法说明:吃东西
     */
    private void eat() {
        try {
            Thread.sleep(firstTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (Wares.useFork()) {
            System.out.println(name + "拿到叉子了1");            
            if (!Wares.useKnife()) {
                waitForKnife(); // 等着拿刀子
            }
            System.out.println(name + "拿到刀子了2");
        } else {
            // 拿不到叉子,去拿刀子            
            if (Wares.useKnife()) {
                System.out.println(name + "拿到刀子了3");
                waitForFork(); //等着拿叉子                
            }else{
                waitForFork();
                waitForKnife();                    
            }
        }
    }

    private void waitForFork() {
        while (true) {
            try {
                Thread.sleep(getTime);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (Wares.useFork()) {
                System.out.println(name + "拿到叉子了5");
                break;
            }
            System.out.println(name + "等着叉子");
        }
    }

    private void waitForKnife() {
        while (true) {
            try {
                Thread.sleep(getTime);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (Wares.useKnife()) {
                System.out.println(name + "拿到刀子了6");
                break;
            }
            System.out.println(name + "等着刀子");
        }
    }

    /**
     * 休息
     */
    private void rest() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name + "休息中");
    }

    /**
     * 归还餐具
     */
    private void done() {
        try {
            Thread.sleep(returnTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Wares.returnWares();
        System.out.println(name + ": 吃完饭了");
    }

}


测试:

public static void main(String[] args) {
        Man man1 = new Man("张三", 1000);
        Man man2 = new Man("李四", 1600);
        man1.start();
        man2.start();
        //ma
//        Thread t1 = new Thread(man1);
//        Thread t2 = new Thread(man2);
//        t1.start();
    }


上面之所以设置不同的第一次等待时间,是为了让结果更加明显!

打印输出结果:

  张三拿到叉子了1
张三拿到刀子了2
李四等着叉子
张三休息中
张三: 吃完饭了
李四拿到叉子了5
李四拿到刀子了6
张三等着叉子
张三等着叉子
李四休息中
李四: 吃完饭了
张三拿到叉子了5
张三拿到刀子了6
李四等着叉子
李四等着叉子
张三休息中
张三: 吃完饭了
李四拿到叉子了5
张三拿到刀子了3
李四等着刀子
张三等着叉子
李四等着刀子
张三等着叉子
李四等着刀子
张三等着叉子
李四等着刀子
张三等着叉子



从结果中可以看出,张三和李四互相等着对方的东西,但又得不到,所以就一直等着了。


0 0
原创粉丝点击