zoukankan      html  css  js  c++  java
  • 线程的死锁和死锁解决的实际案例

    尊重劳动成果,本文是参照https://blog.csdn.net/qq_38638148/article/details/82725191 然后再结合我自己的理解整理的,感谢博主的辛苦付出

    造成死锁的原因:

      死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

    死锁的解除:一旦检测出死锁,就应立即釆取相应的措施,以解除死锁。死锁解除的主要两种方法:

    (1)抢占资源。从一个或多个进程中抢占足够数量的资源,分配给死锁进程,以解除死锁状态。

    (2)终止(或撤销)进程。终止(或撤销)系统中的一个或多个死锁进程,直至打破循环环路,使系统从死锁状态解脱出来。

    先来看死锁:就是多个锁和多个线程之间发生的故事,这里以俩个锁和俩个线程为例子。

    锁1、锁2、线程1、线程2

    当线程1获取锁1之后,线程2也获取了锁2,这是线程1又开始获取锁2(嵌套获取),线程2又想获取锁1(嵌套1获取),这种情况下线程1会等着线程2释放锁2,线程2会等着线程1释放锁1,然后就会形成了死锁。

    具体代码:


    public class deadLock implements Runnable{

    //1.创建俩把锁

    public static final Object object1=new Object();

    public static final Object object2=new Object();

      boolean boo;

    @Override

    public void run() {

      if(boo) {

      synchronized (object1) {

        System.out.println("进入1锁");

        try {

          Thread.sleep(1000);

         } catch (InterruptedException e) {

            e.printStackTrace();

        }

        synchronized (object2) {

          System.out.println("进入2锁");

        }

    }

    }else {

      synchronized(object2) {

      System.out.println("进入2锁");

      try {

        Thread.sleep(1000);

      } catch (InterruptedException e) {

        e.printStackTrace();

      }

            synchronized (object1) {

              System.out.println("进入1锁");

            }

          }

        } 

      }

    }

    测试代码


    public static void main(String[] args) {

    deadLock d1=new deadLock();

    deadLock d2=new deadLock();

    d1.boo=true;

    d2.boo=false;

    Thread t1=new Thread(d1);

    Thread t2=new Thread(d2);

    t1.start();

    t2.start();

    }

    怎么解决呢?

    这种解决方式可以有三种,

    1.顺序取锁

    2.设置锁释放时间(可以使用Lock来实现)

    3.预防死锁

    接下来贴出第一个方式的代码:


    public class openLock implements Runnable{

    public static final Object object=new Object();

    public static final Object object1=new Object();

    boolean bool;

    @Override

    public void run() {

    if(bool) {

    synchronized (object) {

    System.out.println("进入1锁");

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    synchronized (object1) {

    System.out.println("进入二锁");

    }

    }

    }else {

    synchronized (object) {

    System.out.println("进入1锁");

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    synchronized (object1) {

    System.out.println("进入2锁");

    }

    }

    }

    }

    }

    对比死锁的代码来看,其实就是让所有的线程获取所得顺序是一样的,这样子的话就不会存在什么线程死锁的情况出现。

    第二种方法


    public class OpenLock implements Runnable{

    //第二种解决死锁的方式是:给锁设置一个时间,如果超过这个时间的或就放弃获取这个锁。

    Lock l1=new ReentrantLock();//锁1

    Lock l2=new ReentrantLock(); //锁2

    boolean bool;

    @Override

    public void run() {

    if(bool) {

    try {

    l1.lock();

    System.out.println("加上锁1");

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println("现在我在等待进入锁二了");

    if(l2.tryLock(200, TimeUnit.MILLISECONDS)){//注意在判断这一步就已经加上锁了

    try {

    System.out.println("进入锁二");

    }finally {

    l2.unlock();

    }

    }else{

    System.out.println("锁二一直被占用,算了我不进去了");

    }

    } catch (InterruptedException e) {

    e.printStackTrace();

    }finally {

    l1.unlock();

    }

    }else {

    l2.lock();

    try {

    System.out.println("进入锁二");

    Thread.sleep(1000);

    System.out.println("现在我在等待进入锁1了");

    if(l1.tryLock(200,TimeUnit.MILLISECONDS)) {

    try {

    System.out.println("进入锁一");

    }finally {

    l1.unlock();

    }

    }else {

    System.out.println("等带时间太长了,我不等了。");

    }

    } catch (InterruptedException e) {

    e.printStackTrace();

    }finally {

    }

    }

    }

    }

    这种方法就是利用Lock来实现的,Lock锁有一种说法叫做可中断锁,意思是当等待的线程达到一定的时间之后,就不会再去等待了,它会放弃运行这个锁方法,而去执行其他方法。

  • 相关阅读:
    (转载)微软数据挖掘算法应用场景介绍
    (转载)微软数据挖掘算法:Microsoft 目录篇
    (转载)微软数据挖掘算法:Microsoft 线性回归分析算法(11)
    (转载)微软数据挖掘算法:Microsoft 神经网络分析算法(10)
    js分页
    预下载图片,避免图片闪烁
    http协议
    解决&#65279产生的空白行
    兼容ie浏览器的方法
    网站加载速度慢的原因
  • 原文地址:https://www.cnblogs.com/superming/p/12011491.html
Copyright © 2011-2022 走看看