Java 多线程 --死锁及解决方案
在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 多线程 --死锁及解决方案的更多相关文章
- Java 多线程 死锁 隐性死锁 数据竞争 恶性数据竞争 错误解决深入分析 全方向举例
在几乎所有编程语言中,由于多线程引发的错误都有着难以再现的特点,程序的死锁或其它多线程错误可能只在某些特殊的情形下才出现,或在不同的VM上运行同一个程序时错误表现不同.因此,在编写多线程程序时,事先认 ...
- java多线程--死锁
1. Java中导致死锁的原因 Java中死锁最简单的情况是,一个线程T1持有锁L1并且申请获得锁L2,而另一个线程T2持有锁L2并且申请获得锁L1,因为默认的锁申请操作都是阻塞的,所以线程T1和T2 ...
- Java 多线程 - 死锁deadlock产生原因+避免方法
ref: java中产生死锁的原因及如何避免 https://blog.csdn.net/m0_38126177/article/details/78587845 java如何避免死锁 http:// ...
- Java多线程死锁的产生实例
死锁产生的四个必要条件: (1) 互斥条件:一个资源每次只能被一个进程使用.(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放.(3) 不剥夺条件:进程已获得的资源,在末使用完 ...
- Java多线程——死锁
当一个线程永远地持有一个锁,并且其他线程都尝试获得这个锁时,那么他永远被阻塞,当线程A持有锁L并想获得锁M的同时,线程B持有锁M并同时尝试获得锁L时,那么两个线程将永远的等待下去,这中情况就是简单的死 ...
- java 多线程死锁
死锁案例: package com.test; public class DealThread implements Runnable { public String username; public ...
- java多线程死锁
进程(线程)同步的基本概念 进程之间的制约关系 1. 直接制约关系(进程同步) 这个关系主要源于进程合作,例如,有一个输入进程A通过单缓冲向进程B提供数据,当该缓冲空时,进程B因为不能获得所需数据而被 ...
- Java多线程编程核心技术(二)对象及变量的并发访问
本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...
- java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决
0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...
随机推荐
- js Object方法小结
1. Object.defineProperty(obj,prop,{ value:..., writable:boolean,//可写 ...
- Java的浅拷贝与深拷贝总结
Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去.举例说明:比如,对象A和对象B都属于类S,具有属性a和b.那么对对象A进行拷贝 ...
- 关于HashCode和equals方法在HashSet中的使用
Object类是类层次结构的根类,故所有的类都是先该类的方法,其中HashCode()和equals()方法也是该类的方法. 1.HashCode()方法 Object类中HashCode()方法实现 ...
- 《深入理解 Java 虚拟机》读书笔记:线程安全与锁优化
正文 一.线程安全 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那 ...
- 国内 Java 开发者必备的两个装备,你配置上了么?
虽然目前越来越多的国产优秀技术产品走出了国门,但是对于众领域的开发者来说,依然对于国外的各种基础资源依赖还是非常的强.所以,一些网络基本技能一直都是我们需要掌握的,但是速度与稳定性问题一直也都有困扰着 ...
- node.js代码二
var express = require('express'); var app = express(); var server = require('http').Server(app); var ...
- linux 配置 python3 CGI
文章更新于:2020-03-04 注1:安装 python 参见: python 的安装使用和基本语法 注2:配置 web 环境参见: Windows&linux使用集成环境搭建 web 服务 ...
- Aactivity跳转到Bactivity之后再返回Aactivity的几种操作
一个主界面(主Activity)通过意图跳转至多个不同子Activity上去,当子模块的代码执行完毕后再次返回主页面,将子activity中得到的数据显示在主界面/完成的数据交给主Activity处理 ...
- go 结构开发规范
机构规范: // 当前程序的包名 package main //导入其他的包 import "fmt" //常量的定义 const PI=3.14 //全局变量的声明和赋值 var ...
- ensp的基础路由命令,接口,下一跳的配置,入门必备
关于ensp入门事情,第一件事当是安装必备三件套:而后,应该是接触路由和PC机了,最烦人满屏代码,眼花缭乱: 今天写一篇零基础接触ensp的首次操作,PC-路由-路由-PC的互通实验: 实验要拉出两台 ...