死锁原因和解决,预防(简单的demo,简单明了说明死锁,理解死锁);多线程交替执行任务(synchronized+ wait+notify 实现)

死锁:两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法执行下去。

下面通过一个简单的demo ,说明死锁的形成。

package com.stcn.news.util;

public class ThreadDemo {
    public static void main(String[] args) {
        Object lock1=new Object();
        Object lock2=new Object();
        Thread t1=new Thread(new myThead(lock1,lock2),"t1");
        Thread t2=new Thread(new myThead(lock2,lock1),"t2");
        t1.start();
        t2.start();
    }
    public  static class myThead  implements Runnable {
        private Object locker1;
        private Object locker2;

        public myThead(Object locker1, Object locker2) {
            this.locker1 = locker1;
            this.locker2 = locker2;
        }

        @Override
        public void run() {
            synchronized(locker1) {  // @1
                System.out.println(Thread.currentThread().getName()+ " 获取锁:"+locker1);  // @2
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(locker2) {    // @3
                    System.out.println(Thread.currentThread().getName()+ " 获取锁:"+locker2);  // @4

                    /**
                     * 这里永远执行不到;
                     *  代码 @1,@2行 : t1  先进来,获取到了 locker1对象 ; 而t2 进来获取了  locker2对象
                     *  代码 @3,@4行 : t1 想获取 locker2对象 执行 @4行代码,发现 t2 正在占用 locker2对象 ,t1 此时无法执行下去;
                     *                而t2 想获取 locker1 对象,执行@4行代码,发现t1 正在占用 locker1 对象,t2 此时无法执行下去;
                     *   所以造成这个这种僵持的状态:死锁
                     */
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println("锁被释放了,我被执行了。。。。。。。。。。。。");
        }
    }
}

 死锁的产生的必要条件:

  1. 互斥条件:一个线程访问资源时候,其他线程不可访问。

  2. 请求与保持条件: 一个线程请求资源未获取,则持续请求。

  3. 不可剥夺条件: 一个线程保持这个资源,那么在它释放资源之前,其他线程无法抢夺。

  4. 彼此循坏等待:多个线程彼此等待一个资源的释放

死锁解决和预防:

  1. 加锁的顺序:各个线程按照一定顺序加锁。

  2. 锁的时限设置:万一出现死锁,可保证一定时间内资源得到释放。

  3. 加锁前的检验:主要预防死锁的产生。

多线程交替执行任务(synchronized+ wait+notify 实现):

package com.stcn.news.util;

/**
 * 多个线程交替执行任务 synchronized+ wait+notify 实现
 * @author 86136
 */
public class ThreadChangeExcut {
    /**
     * volatile  保证变量可见性
     */
    public static volatile int  count = 10;
    /**
     * 线程申请的同一把锁
     */
    public static  Object lock=new Object();

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(lock) {
                    while (count>0) {
                        if(count % 2 == 0){
                            try {
                                lock.wait();   // 释放锁进入等待队列(等待池),线程2获取到对象锁
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        count--;
                        if(count >= 0){
                            System.out.println("当前线程:"+Thread.currentThread().getName()+ "---->B");
                        }
                        lock.notify();         // 唤醒等待队列中线程2进入锁池竞争对象锁
                    }
                }

            }
        },"t1").start();
        new Thread(new Runnable() {

            @Override
            public void run() {
                synchronized(lock) {
                    while (count > 0) {
                        if (count % 2 != 0) {
                            try {
                                lock.wait();   // 释放锁进入等待队列(等待池),线程1获取到对象锁
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        count--;
                        if (count >= 0) {
                            System.out.println("当前线程:"+Thread.currentThread().getName()+ "---->A");
                        }
                        lock.notify();         // 唤醒等待队列中线程1进入锁池竞争对象锁
                    }
                }
            }
        },"t2").start();

    }


}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值