• 2017.10.4 操作系统---死锁的定义与分析


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

    当然死锁的产生是必须要满足一些特定条件的: 
    1.互斥条件:进程对于所分配到的资源具有排它性,即一个资源只能被一个进程占用,直到被该进程释放 
    2.请求和保持条件:一个进程因请求被占用资源而发生阻塞时,对已获得的资源保持不放。 
    3.不剥夺条件:任何一个资源在没被该进程释放之前,任何其他进程都无法对他剥夺占用 
    4.循环等待条件:当发生死锁时,所等待的进程必定会形成一个环路(类似于死循环),造成永久阻塞。

    package com.legend.domain;

    import java.util.Date;

    /**

    * 死锁案例

    * @author qichunlin

    *

    */

    public class LockTest {

    public static String obj1 = "obj1";

    public static String obj2 = "obj2";

    public static void main(String[] args) {

    LockA la = new LockA();

    new Thread(la).start();

    LockB lb = new LockB();

    new Thread(lb).start();

    }

    }

    class LockA implements Runnable {

    public void run() {

    try {

    System.out.println(new Date().toString() + " LockA 开始执行");

    while (true) {

    synchronized (LockTest.obj1) {

    System.out.println(new Date().toString() + " LockA 锁住 obj1");

    Thread.sleep(3000); // 此处等待是给B能锁住机会

    synchronized (LockTest.obj2) {

    System.out.println(new Date().toString() + " LockA 锁住 obj2");

    Thread.sleep(60 * 1000); // 为测试,占用了就不放

    }

    }

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    class LockB implements Runnable {

    public void run() {

    try {

    System.out.println(new Date().toString() + " LockB 开始执行");

    while (true) {

    synchronized (LockTest.obj2) {

    System.out.println(new Date().toString() + " LockB 锁住 obj2");

    Thread.sleep(3000); // 此处等待是给A能锁住机会

    synchronized (LockTest.obj1) {

    System.out.println(new Date().toString() + " LockB 锁住 obj1");

    Thread.sleep(60 * 1000); // 为测试,占用了就不放

    }

    }

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

     

     

    此时死锁产生。

    为了解决这个问题,我们不使用显示的去锁,我们用信号量去控制。

    信号量可以控制资源能被多少线程访问,这里我们指定只能被一个线程访问,就做到了类似锁住。而信号量可以指定去获取的超时时间,我们可以根据这个超时时间,去做一个额外处理。

    对于无法成功获取的情况,一般就是重复尝试,或指定尝试的次数,也可以马上退出。

  • 相关阅读:
    Spring 实例化bean的三种方式
    Mybatis和Hibernate比较
    MyBatis学习总结(一)——MyBatis快速入门
    Java EE的十三个规范
    Python 测试代码覆盖率统计工具 coverage.py
    mysql explain执行计划详解
    Django模型的Field Types
    使程序在Linux下后台运行,程序运行前后台切换
    ubuntu中将本地文件上传到服务器
    Python-内置函数小结
  • 原文地址:https://www.cnblogs.com/qichunlin/p/7628066.html
Copyright © 2020-2023  润新知