一,什么是死锁?

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

二,死锁产生的条件?

  (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. python django Form表单

    Django 拥有自己独立的表单功能块,可以完成: 1.表单的定义 2.表单的校验 3.表单的前端样式 等功能,方便我们开发,那么接下来,我们看一下表单的定义 首先我们确定我们要编写的功能,一个提供给 ...

  2. 【LeetCode】226. 翻转二叉树

    题目 翻转一棵二叉树. 示例: 输入: 4 / \ 2 7 / \ / \ 1 3 6 9 输出: 4 / \ 7 2 / \ / \ 9 6 3 1 本题同[剑指Offer]面试题27. 二叉树的镜 ...

  3. Mac 设置git的template

    1.在home目录下修改.gitconfig(没有新建) 2. 在home下新建 .setCommitMsg 文件 3.然后将一下内容复制到文件中 # <类型>: (类型的值见下面描述) ...

  4. Ubuntu不会放弃32位应用程序

    Ubuntu 开发人员澄清,人们以为 Ubuntu 将在 Ubuntu 19.10 和后续版本中放弃对运行 32 位应用程序的支持,但“根本不是这种情况”.那么这究竟是怎么一回事呢?前几天 Ubunt ...

  5. netty权威指南学习笔记一——NIO入门(3)NIO

    经过前面的铺垫,在这一节我们进入NIO编程,NIO弥补了原来同步阻塞IO的不足,他提供了高速的.面向块的I/O,NIO中加入的Buffer缓冲区,体现了与原I/O的一个重要区别.在面向流的I/O中,可 ...

  6. python基础笔记:判断与循环

    判断: #根据身高为1.75,体重为65的小明的bmi输出小明的身材 h=1.75 w=65 bmi=w/(h*h) if bmi<18.5: print('过轻') elif bmi<= ...

  7. Springboot跨域 ajax jsonp请求

    SpringBoot配置: <dependency> <groupId>org.springframework.boot</groupId> <artifac ...

  8. 九十五、SAP中查看自定义包的所有模块,对象,函数主,事务等

    一.输入SE80 二.选择包,再查下Z* 三.可以看到,查下出来的包 四.可以看到我们想要的内容了

  9. PhotoView 实现与图片进行简单的交互

    本文的category是根据VIPhotoView来做参考,在此基础上添加个加载网络图片. 此category主要功能是与图片进行交互,双击放大图片,捏合等操作. 感谢vitoziv ! VIPhot ...

  10. AIDL使用绑定启动远程Service出现Service Intent must be explicit: Intent

    Intent intent = new Intent(); intent.setAction("remote.MyRemoteService.Action"); 使用AIDL调用远 ...