一,什么是死锁?

  所谓的死锁是指多个线程因为竞争资源而造成的一种僵局(相互等待),若无外力的作用,这些进程都不能向前推进。

二,死锁产生的条件?

  (1)互斥条件:线程要求对所分配的资源(如打印机)进行排他性控制,既在某一段时间内,资源只能被一个线程所占有。

  (2)不剥夺条件:线程所获得的资源在未使用完前,不能被其他的线程强行夺走,只能由该线程自己释放。

  (3)请求和保持的条件:线程已经保持了一个 资源,但又提出了新的资源请求,而该资源被其他的线程所占用,此时请求进程被阻塞,但对自己的资源也不会释放。

  (4)循环等待条件:存在一种线程资源的循环等待链,链中的每一个线程已获得的资源同时被链中下一个线程所请求。

三,产生死锁的一个例子

package com.itheima.gan;
/**
* 一个简单的死锁类
* @author 12428
* 当DeadLock类的对象flag==1时,(td1)先锁定o1,睡眠500毫秒
* 在td1睡眠的时候,另一个类对象的flag==0,(td2)线程启动,先锁定o2,睡眠500毫秒
* 静态属性是类的所有对象所共有的。
* 在td1睡眠结束的时候需要锁定o2才能继续执行,而此o2已被td2锁定
* td2 睡眠结束后需要锁定 o1 才能继续执行,而此时 o1 已被 td1 锁定;
* td1、td2 相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。
*
*/
public class DeadLock implements Runnable{ public int flag=1; //静态对象是类的所有对象共享的
private static Object o1=new Object(),o2=new Object(); @Override
public void run() {
System.out.println("flag = "+flag); if(flag==1) {
synchronized(o1) { try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
} synchronized (o2) {
System.err.println("2");
}
}
} if(flag==0) {
synchronized (o2) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
} synchronized (o1) {
System.out.println("3");
}
}
}
} public static void main(String[] args) {
DeadLock td1=new DeadLock();
DeadLock td2=new DeadLock(); td1.flag=1;
td2.flag=0; //td1,td2都处于可执行的状态,但虚拟机调用那个线程是未知的
new Thread(td1).start();
new Thread(td2).start();
}
}

四,处理死锁的方法

(1)加锁的顺序(线程按照一定的顺序来加锁)

package com.itheima.gan;
/*
* 如何避免死锁
* 加锁的顺序
*/
public class DeadLock2 {
public int flag=1;
//静态对象是类的所有对象共享的
private static Object o1=new Object(), o2=new Object(); public void money(int flag) { this.flag=flag; if(flag==1) {
synchronized(o1) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(o2) {
System.out.println("当前线程是"+Thread.currentThread().getName()+
" "+" flag的值是 :"+flag);
}
}
} if(flag==0) {
synchronized(o2) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(o1) {
System.out.println("当前线程是"+Thread.currentThread().getName()+
" "+" flag的值是 :"+flag);
}
}
}
} public static void main(String[] args) {
final DeadLock2 td1=new DeadLock2();
final DeadLock2 td2=new DeadLock2(); td1.flag=1;
td2.flag=0; final Thread t1=new Thread(new Runnable() {
@Override
public void run() {
td1.flag=1;
td1.money(1); }
});
t1.start(); Thread t2=new Thread(new Runnable() {
@Override
public void run() {
try {
//核心代码,让线程2在线程1执行完在执行,下面join方法的作用是当前线程放弃cpu的执行权,返回到t1线程执行的地方,直到t1线程执行完,再继续向下执行。
t1.join();
}catch (Exception e) {
e.printStackTrace();
} td2.flag=0;
//调用方法
td2.money(0);
}
}); t2.start();
}
}

Java线程——线程之间的死锁的更多相关文章

  1. Java之线程,常用方法,线程同步,死锁

    1, 线程的概念 进程与线程 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据 ...

  2. Java多线程——线程之间的协作

    Java多线程——线程之间的协作 摘要:本文主要学习多线程之间是如何协作的,以及如何使用wait()方法与notify()/notifyAll()方法. 部分内容来自以下博客: https://www ...

  3. Java多线程——线程的死锁

    Java多线程——线程的死锁 摘要:本文主要介绍了Java多线程中遇到的死锁问题. 部分内容来自以下博客: https://www.cnblogs.com/wy697495/p/9757982.htm ...

  4. Java多线程——线程之间的同步

    Java多线程——线程之间的同步 摘要:本文主要学习多线程之间是如何同步的,如何使用volatile关键字,如何使用synchronized修饰的同步代码块和同步方法解决线程安全问题. 部分内容来自以 ...

  5. 进阶Java编程(3)线程的同步与死锁

    线程的同步与死锁 1,同步问题引出 在多线程的处理之中,可以利用Runnable描述多个线程操作的资源,而Thread描述每一个线程对象,对于当多个线程访问统一资源的时候如果处理不当就会产生数据的错误 ...

  6. Java线程——线程之间的数据共享

      在 Java 传统线程机制中的共享数据方式,大致可以简单分两种情况: ➢ 多个线程行为一致,共同操作一个数据源.也就是每个线程执行的代码相同,可以使用同一个 Runnable 对象,这个 Runn ...

  7. java 线程(六)死锁

    package cn.sasa.demo4; public class ThreadDemo { public static void main(String[] args){ DeadLockRun ...

  8. 菜鸡的Java笔记 - java 线程的同步与死锁 (同步 synchronization,死锁 deadlock)

    线程的同步与死锁 (同步 synchronization,死锁 deadlock)        多线程的操作方法            1.线程同步的产生与解决        2.死锁的问题     ...

  9. Java的线程安全

    线程安全 我们这里讨论的线程安全,就限定于多个线程之间存在共享数据访问这个前提,因为如果一段代码根本不会与其他线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它来说是完全没有区别 ...

  10. Java并发——线程安全、线程同步、线程通信

    线程安全 进程间"共享"对象 多个“写”线程同时访问对象. 例:Timer实例的num成员,即add()方法是用的次数.即Timer实例是资源对象. class TestSync ...

随机推荐

  1. UVA 12510/CSU 1119 Collecting Coins DFS

    前年的省赛题,难点在于这个石头的推移不太好处理 后来还是看了阳神当年的省赛总结,发现这个石头这里,因为就四五个子,就暴力dfs处理即可.先把石头当做普通障碍,进行一遍全图的dfs或者bfs,找到可以找 ...

  2. python面试总结知识点

    1.python中is和==的区别 Python中对象包含的三个基本要素,分别是:id(身份标识) .type(数据类型)和value(值). ‘==’比较的是value值 ‘is’比较的是id 2. ...

  3. 前端 移动端H5页面 DEBUG

    下载网址:https://github.com/Tencent/vConsole 把这个JS复制到项目里面 然后引入到HTML中 然后在JS上面实例化一下即可 页面就会有一个绿色的,然后点击一下就可以 ...

  4. WMware workstation 镜像文件

    https://mirrors.aliyun.com/centos/7.4.1708/isos/x86_64/

  5. 《ES6标准入门》(阮一峰)--7.数值的扩展

    1.二进制和八进制表示法 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示. 0b111110111 === 503 // true 0o767 === 503 ...

  6. HDU - 6195 cable cable cable

    题意:如下图,有K个光源,一个光源可同时照射一个显示屏,问从M个显示屏中任选K个,可以使每个显示屏都被不同光源照亮最少需要多少连接电缆. 分析:画图分析可知 1.选1~K个显示屏和选M-K+1~M个显 ...

  7. 文本编辑器vim/vi——命令模式

    一个完整的指令的标准格式: Linux通用的格式——#指令主体(空格) [选项](空格) [操作对象] 一个指令可以包含多个选项,操作对象也可以是多个. vim指令: 指令:vim   (vim是一款 ...

  8. 119-PHP调用private成员的方法

    <?php class ren{ //定义人类 private $birthday='1990-12-20'; //定义private修饰的成员属性 public function say_bi ...

  9. 075-PHP数组添加元素

    <?php $arr = array(); //定义一个数组,它没有任何元素 echo '增加元素之前数组中元素的个数为:' . count($arr); //输出数组个数 for ($i = ...

  10. Java 统计整数二进制中1的个数

    package cookie; public class CountBinary_1 { public static void main(String[] args) { System.out.pri ...