一,什么是死锁?

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

二,死锁产生的条件?

  (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. 007-PHP变量和函数相互转换

    <?php function write($text) //定义function write()函数 { print($text); //打印字符串 } function writeBold($ ...

  2. 配置gem5-gpu docker版

    1 安装docker:wget -qO- https://get.docker.com/ | sh,启动服务:sudo service docker start 2 把非root用户添加到docker ...

  3. https://blog.csdn.net/yyoinge/article/details/81557604

    https://blog.csdn.net/yyoinge/article/details/81557604 http://www.mamicode.com/info-detail-2346464.h ...

  4. delphi10.2 命令行编译x64脚本

    Build.bat @echo off @echo delphi x64编译测试 @cd /d %~dp0 @echo 设置Delphi参数信息 @set SourcePath=%~dp0.\src ...

  5. 《从Lucene到Elasticsearch全文检索实战》的P184页

    curl -XPOST "http://localhost:9200/_bulk?pretty" --data-binary @books.json 这句话在书中是以crul的命令 ...

  6. LeetCode题解汇总(包括剑指Offer和程序员面试金典,持续更新)

    LeetCode题解汇总(持续更新,并将逐步迁移到本博客列表中) LeetCode题解分类汇总(包括剑指Offer和程序员面试金典) 剑指Offer 序号 题目 难度 03 数组中重复的数字 简单 0 ...

  7. node核心 http模块

    node作为服务器更多的是web服务器 1.http模块 首先:http是一个协议.里面有通信机制,状态码一大堆乱七八糟的东西.自己写猴年马月都写不出来,这个对象帮我们集成.直接用 服务器对象: ht ...

  8. postman带上token对接口进行测试

    根据验证码进行登陆,登录之后返回token.然后请求其他接口时在header头中带上token访问其他接口进行测试 账户信息输入验证码 登陆成功,看到返回的token 我们这个项目可以刷新一下toke ...

  9. python 求两个数的最大公约数

    给定两个整数a,b,求他们的最大公约数 def gcd(a,b): if a<b: a,b=b,a while(a%b != 0): c = a%b a=b b=c return b a,b = ...

  10. java核心-多线程(1)-知识大纲

    Thread,整理一份多线程知识大纲,大写意 1.概念介绍 线程 进程 并发 2.基础知识介绍 Java线程类 Thread 静态方法&实例方法 Runnable Callable Futur ...