在java 多线程中 过多的同步造成相互不释放资源 从而相互等待,造成死锁线现象,一般发生于同步中持有多个对象锁

如以下代码:

public class DeadLock {
public static void main(String[] args) {
WuDao wd1 = new WuDao(0, "金毛狮王");
WuDao wd2 = new WuDao(1, "灭绝师太");
wd1.start();
wd2.start();
}
} // 屠龙刀
class TuLongDao { } // 倚天剑
class YiTianJian { } class WuDao extends Thread {
static TuLongDao tld = new TuLongDao();
static YiTianJian ytj = new YiTianJian();
// 选择
int choice;
// 名字
String name; @Override
public void run() {
// 悟道
wudao();
} public WuDao(int choice, String name) {
super();
this.choice = choice;
this.name = name;
} private void wudao() {
if (choice == 0) {
synchronized (tld) { // 获得屠龙刀锁
System.out.println(this.name + "领悟屠龙刀法");
// 1秒后想拥有倚天剑锁
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (ytj) {
System.out.println(this.name + "领悟武穆遗书");
}
}
} else {
synchronized (ytj) { // 获得倚天锁
System.out.println(this.name + "领悟倚天剑法");
// 2秒后想拥有屠龙刀锁
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (tld) {
System.out.println(this.name + "领悟九阴真经");
}
}
}
}
}

运行以上代码:

可以看到:由于发生死锁,程序不能继续运行

解决方案:

不要在同一代码块中,同时持有多个对象锁。

我们只要把synchronized 代码块中的第二个锁往外移一下就可以了,修改后代码如下:

private void wudao() {
if (choice == 0) {
synchronized (tld) { // 获得屠龙刀锁
System.out.println(this.name + "领悟屠龙刀法");
// 1秒后想拥有倚天剑锁
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/*synchronized (ytj) {
System.out.println(this.name + "领悟武穆遗书");
}*/
}
synchronized (ytj) {
System.out.println(this.name + "领悟武穆遗书");
}
} else {
synchronized (ytj) { // 获得倚天锁
System.out.println(this.name + "领悟倚天剑法");
// 2秒后想拥有屠龙刀锁
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/*synchronized (tld) {
System.out.println(this.name + "领悟九阴真经");
}*/
}
synchronized (tld) {
System.out.println(this.name + "领悟九阴真经");
}
}
}

再次运行修改后代码:



代码可以正常运行了。

Java 多线程 --死锁及解决方案的更多相关文章

  1. Java 多线程 死锁 隐性死锁 数据竞争 恶性数据竞争 错误解决深入分析 全方向举例

    在几乎所有编程语言中,由于多线程引发的错误都有着难以再现的特点,程序的死锁或其它多线程错误可能只在某些特殊的情形下才出现,或在不同的VM上运行同一个程序时错误表现不同.因此,在编写多线程程序时,事先认 ...

  2. java多线程--死锁

    1. Java中导致死锁的原因 Java中死锁最简单的情况是,一个线程T1持有锁L1并且申请获得锁L2,而另一个线程T2持有锁L2并且申请获得锁L1,因为默认的锁申请操作都是阻塞的,所以线程T1和T2 ...

  3. Java 多线程 - 死锁deadlock产生原因+避免方法

    ref: java中产生死锁的原因及如何避免 https://blog.csdn.net/m0_38126177/article/details/78587845 java如何避免死锁 http:// ...

  4. Java多线程死锁的产生实例

    死锁产生的四个必要条件: (1) 互斥条件:一个资源每次只能被一个进程使用.(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放.(3) 不剥夺条件:进程已获得的资源,在末使用完 ...

  5. Java多线程——死锁

    当一个线程永远地持有一个锁,并且其他线程都尝试获得这个锁时,那么他永远被阻塞,当线程A持有锁L并想获得锁M的同时,线程B持有锁M并同时尝试获得锁L时,那么两个线程将永远的等待下去,这中情况就是简单的死 ...

  6. java 多线程死锁

    死锁案例: package com.test; public class DealThread implements Runnable { public String username; public ...

  7. java多线程死锁

    进程(线程)同步的基本概念 进程之间的制约关系 1. 直接制约关系(进程同步) 这个关系主要源于进程合作,例如,有一个输入进程A通过单缓冲向进程B提供数据,当该缓冲空时,进程B因为不能获得所需数据而被 ...

  8. Java多线程编程核心技术(二)对象及变量的并发访问

    本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...

  9. java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决

    0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...

随机推荐

  1. arcgis server10.7修改打印模板后前台调用不生效

    在10.5.1及之前的版本中,如果更改打印地图模板,如字体设置,那么直接修改[ArcGIS for Server 安装目录]/Templates/ExportWebMapTemplates下的mxd的 ...

  2. pthread_rwlock_t

    一.读写锁 读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作. 读操作可以共享,写操作是排他的,可以有多个在读(与 CP ...

  3. 在C#MVC三层项目中如何使用SprintNet

    0.添加dll文件 1.首先在根目录下新建一个文件夹[Config],然后新建2两个xml文件. 1-1[controllers.xml]用来配置需要创建的对象 1-2[service.xml]用来配 ...

  4. 使用Spring管理数据库事务

    在整个JavaWeb项目开发中,事务是用来开发可靠性网络应用程序的最关键部分.当应用程序与后端资源进行交互时,就会用到事务,这里的后端资源包括数据库.MQ.ERP等.而数据库事务是最常见的类型,而我们 ...

  5. ㊙力荐!!!那些炒鸡有用的chrome插件㊙

    今天咱们来说一说那些炒鸡

  6. 【WPF学习】第六十二章 构建更复杂的模板

    在控件模板和为其提供支持的代码之间又一个隐含约定.如果使用自定义控件模板替代控件的标准模板,就需要确保新模板能够满足控件的实现代码的所有需要. 在简单控件中,这个过程比较容易,因为对模板几乎没有(或完 ...

  7. Elasticsearch7.6学习笔记1 Getting start with Elasticsearch

    Elasticsearch7.6学习笔记1 Getting start with Elasticsearch 前言 权威指南中文只有2.x, 但现在es已经到7.6. 就安装最新的来学下. 安装 这里 ...

  8. vue 动态添加body背景图片

    <script> export default {   data () {     return {      bodyBgImage: 'url(' + require('../asse ...

  9. jenkins 脱机下 安装插件失败

    1.首次进入,提示离线 2.网上给出了绝大部分答案是进入Manage Plugins 中在高级下将升级站点的https换成http,但是都没解决我的问题  还是报错,用了大部分时间查阅 最终才发现问题 ...

  10. springboot 切面添加日志功能

    1.新建一个springboot项目 2.定义个切面类,并指定切入点,获取所需记录信息(如:访问人IP, 访问地址,访问地址名称等) 3.新建数据库 SET FOREIGN_KEY_CHECKS=0; ...