死锁 简单了解

1、什么是死锁
1.1:死锁定义:
死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
1.2:死锁产生条件:
1)互斥条件:某个资源某一时刻只能由一个线程占用
2)不可抢占条件:资源申请者不能从资源占有者手中抢夺资源
3)占有且申请:线程至少已经占有一个资源,但又去申请新的资源,新资源被占用,该线程会阻塞
4)循环等待:一个线程等待另外一个线程释放资源,另外一个线程又去等待,直到最后一个线程等待第一个线程释放资源,使得大家都被锁住

2、常见死锁
2.1:交叉锁
若线程A访问R1(获得锁R1),后访问R2,同时线程B访问R2(获得锁R2),后访问R1;
因R1、R2被锁,线程A 、B无法继续,产生死锁

private final Object R1 = new Object();
private final Object R2 = new Object();


//线程A
public void func1(){
    synchronized (R1){
        synchronized (R2){
            //dosomething
        }
    }
}

//线程B
public void func2(){
    synchronized (R2){
        synchronized (R1){
            //dosomething
        }
    }
}

.2:内存不足
若线程A需要内存40MB。线程B需要内存50MB,现在线程A已有10MB,还需要30MB;线程B有10MB,需要40MB,系统内存只剩30MB,内存不足,无法进行合理分配,产生死锁

2.3:一问一答的数据交换
在网络中,服务器端(server)等待客户端(client)的访问,client发送请求到server中,需要等待接收数据,若因为网络原因,server错过client的请求,server和client就会一直等待,产生死锁。
2.4:死循环引起的死锁
如下列代码,本身本身死循环,但在这个循环中,使用了一些开源的东西,调用层次比较深,就有可能出现死锁问题

private static HashMap<String, String> map = new HashMap<>();

        for(int i=0; i<2; i++){
            new Thread(){
                @Override
                public void run() {
                    for(int i=0; i<Integer.MAX_VALUE; i++ ){
                        map.put(String.valueOf(i), String.valueOf(i));
                    }
                }
            }.start();
        }

3、死锁的避免、检测
3.1:死锁的预防
1)允许某些线程同时访问某些资源
2)允许线程强行去夺取某些资源
3)允许实现资源预分配策略
4)线程按照编号申请资源
3.2:死锁的避免
安全序列: 如果系统按照这种序列去分配资源,每个线程都能够顺序完成自己的需求,这样序列就是安全序列,系统称之为安全状态。安全序列可能会有多个。
如果系统处于安全状态,就一定不会发生死锁;如果系统处于不安全状态,就"可能"会发生死锁。
4、哲学家就餐问题
问题:有5位哲学家围在圆桌就餐,每个哲学家左边旁边只有一张筷子,若一个哲学家进行思考,旁边的人就会试图获得最靠近它的筷子,只有两个筷子才能就餐,就餐完毕后,放下筷子进行思考。

Chopstick{
    //key为筷子的编号,value是筷子的标识别
    private static HashMap<Integer, Boolean> map = new HashMap<>();

    static{
        map.put(0, false);
        map.put(1, false);
        map.put(2, false);
        map.put(3, false);
        map.put(4, false);
    }

    public synchronized void getChopstick(){
        String curName = Thread.currentThread().getName();

        int leftChop = Integer.parseInt(curName); //左边筷子
        int rightChop = (leftChop+1) % 5; //右边筷子

        //判断左右两边的筷子是否都可用
        while(map.get(leftChop) || map.get(rightChop)){
            try {
                this.wait();//表示两双筷子未能同时可用,哲学家陷入思考,线程阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        map.put(leftChop, true);
        map.put(rightChop, true);

        System.out.println("Thread "+curName+" got the chopsticks "+leftChop+" and "+rightChop);

    }

    public synchronized void freeChopstick(){
        String curName = Thread.currentThread().getName();
        int leftChop = Integer.parseInt(curName); //左边筷子
        int rightChop = (leftChop+1) % 5; //右边筷子
        map.put(leftChop, false);
        map.put(rightChop, false);
        this.notifyAll();
    }
}

public class TestDemo8 {
    public static void main(String[] args) {
        Chopstick chopstick = new Chopstick();
        for(int i=0; i<5; i++){
            new Thread(String.valueOf(i)){
                @Override
                public void run() {
                    //当前线程获得两边筷子,准备就餐
                  //  while(true){
                        chopstick.getChopstick();
                        System.out.println("Thread " +Thread.currentThread().getName()+" is eating");
                        try {

                            TimeUnit.MILLISECONDS.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        chopstick.freeChopstick();
               //     }
                }
            }.start();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值