在java开发中,避免不了要加锁控制程序逻辑,但加锁有可能导致死锁,造成线程永远卡死在等待释放锁,后面的代码得不到执行; 
在java里,一般是通过synchronized关键字加锁,在jdk1.5版本中新增了Lock接口显示的加锁,本文讨论用这两种方式实现死锁; 
方式一:

public static void main(String[] args) {
Object lock1 = new Object();
Object lock2 = new Object();
ExecutorService service = Executors.newCachedThreadPool();
service.execute(() ->{
while (true){
synchronized (lock2){
synchronized (lock1){
System.out.println("Thread1");
}
}
}
});
service.execute(() ->{
while (true){
synchronized (lock1){
synchronized (lock2){
System.out.println("Thread2");
}
}
}
});
service.shutdown();
}

上面的代码开启了两个线程,两个线程都循环打印字符串,正常来说两个线程都会不断打印,但这里出现了死锁,导致两个线程都会打印停止,逻辑分析:两个线程执行到某一时刻,线程一执行到synchronized (lock2){这一句,获得了对象lock2上的锁,线程二执行到synchronized (lock1){这一句,获得了对象lock1上的锁,接下来,线程一需要执行synchronized (lock1){这一句尝试获取lock1的锁,由于lock1的锁被线程二占用,线程一等待线程二释放lock1的锁,这时线程二需要执行synchronized (lock2){这一句,尝试获取lock2上的锁,由于lock2上的锁被线程一占用,线程二等待线程一释放lock2上的锁,这样,两个线程互相等待释放锁,导致两个线程永远无法执行后面的代码,导致死锁; 
方式二:

static final Lock LOCK1 = new ReentrantLock();
static final Lock LOCK2 = new ReentrantLock();
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
service.execute(new PrintTask1(1));
service.execute(new PrintTask2(2)); }
static class PrintTask1 implements Runnable{
private int id = -1;
public PrintTask1(int i){
id = i;
}
@Override
public void run() {
while (true){
LOCK1.lock();
LOCK2.lock();
System.out.println("" + id);
LOCK2.unlock();
LOCK1.unlock();
}
}
} static class PrintTask2 implements Runnable{
private int id = -1;
public PrintTask2(int i){
id = i;
}
@Override
public void run() {
while (true){
LOCK2.lock();
LOCK1.lock();
System.out.println("" + id);
LOCK2.unlock();
LOCK1.unlock();
}
}
}

方式二的代码属于显示加锁,使用了jdk1.5新增的Lock接口,与方式一类似,当两个线程执行到某一时刻,线程一执行了LOCK1.lock()获得了LOCK1锁,线程二执行了LOCK2.lock()获得了LOCK2锁,接下来两个线程又要互相等待对方释放锁,导致死锁。

JAVA死锁的写法的更多相关文章

  1. 实例详解 Java 死锁与破解死锁

    锁和被保护资源之间的关系 我们把一段需要互斥执行的代码称为临界区.线程在进入临界区之前,首先尝试加锁 lock(),如果成功,则进入临界区,此时我们称这个线程持有锁:否则呢就等待,直到持有锁的线程解锁 ...

  2. Java死锁排查和Java CPU 100% 排查的步骤整理

    ================================================= 人工智能教程.零基础!通俗易懂!风趣幽默!大家可以看看是否对自己有帮助! 点击查看高清无码教程 == ...

  3. Java 链式写法

    Java链式写法,子类继承父类的属性,也可以返回子类的对象,只是需要重写基类的Set方法 public class MyLS { public static void main(String[] ar ...

  4. 一文学会Java死锁和CPU 100% 问题的排查技巧

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开 工欲善其事,必先利其器 00 本文简介 作为一名搞技术的程序猿或者是攻城狮,想必你应该是对下面这两个问题有所了解,说不定你在 ...

  5. Java死锁演示

    Java死锁演示 在线程中嵌套获取锁导致死锁.思路,尽量不要嵌套获取锁. package com.mozq.demo.demo; public class DeadLockDemo { private ...

  6. 【性能优化】一文学会Java死锁和CPU100%问题的排查技巧

    原文链接: 00 本文简介 作为一名搞技术的程序猿或者是攻城狮,想必你应该是对下面这两个问题有所了解,说不定你在实际的工作或者面试就有遇到过: 第一个问题:Java死锁如何排查和解决? 第二个问题:服 ...

  7. java 死锁演示

    java 死锁演示 java死锁 模拟死锁生成 死锁是由多个线程竞争同一个资源导致 package com.feshfans; /** * 1. 本代码为展示 java 中死锁的产生 * 2. 死锁的 ...

  8. Java链式写法

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11613067.html Java 链式写法:详细看代码 package chain; /** ...

  9. Java 死锁以及如何避免?

    Java 中的死锁是一种编程情况,其中两个或多个线程被永久阻塞,Java 死锁情况 出现至少两个线程和两个或更多资源. Java 发生死锁的根本原因是:在申请锁时发生了交叉闭环申请.

随机推荐

  1. luogu3778/bzoj4898 商旅 (floyd+分数规划+spfa)

    首先floyd求出来每两点间的最短距离,然后再求出来从某点买再到某点卖的最大收益 问题就变成了找到一个和的比值最大的环 所以做分数规划,二分出来那个答案r,把边权变成w[i]-r*l[i],再做spf ...

  2. 【bzoj3992】 SDOI2015—序列统计

    http://www.lydsy.com/JudgeOnline/problem.php?id=3992 (题目链接) 题意 集合${S}$中有若干个不超过${m}$的非负整数,问由这些数组成一个长度 ...

  3. 前端学习 -- Css -- 内联元素的盒模型

    内联元素不能设置width和height: 设置水平内边距,内联元素可以设置水平方向的内边距:padding-left,padding-right: 垂直方向内边距,内联元素可以设置垂直方向内边距,但 ...

  4. Cocos2d-x 3.2 打包Android平台APK

    (转自:http://www.cnblogs.com/Richard-Core/p/3855130.html) 从cocos2dx 3.2项目打包成apk安卓应用文件,搭建安卓环境的步骤有点繁琐,但搭 ...

  5. Redis常用命令速查 <第二篇>

    一.Key Key命令速查: 命令 说明 DEL 删除给定的一个或多个 key,不存在的 key 会被忽略,返回值:被删除 key 的数量 DUMP 序列化给定 key,返回被序列化的值,使用 RES ...

  6. Linux上查找

    locate 用法:locate filename locate是Linux系统中的一个查找(定位)文件命令,和find命令等找寻文件的工作原理类似,但locate是通过生成一个文件和文件夹的索引数据 ...

  7. java基础基础总结----- StringBuffer(重要)

    前言StringBuffer:(常用的方法) StringBuffer与StringBuilder的区别 关于安全与不安全的解释:

  8. ThreadLocal实现线程范围的共享变量

    一.如何理解线程范围内共享数据 1.static int num=0; 2.线程1访问num变量,并设置为num=2:线程2访问num变量,并设置为num=3: 3.当线程1中对象A.B.C 在访问线 ...

  9. 基于 Express 搭建一个node项目 - 起步

    一,如何基于 Express 搭建一个node项目 什么是Express 借用官方的介绍,Express是一个基于Node.js平台的极简.灵活的web应用开发框架,它提供了一系列强大的特性,帮助你创 ...

  10. [转载]AngularJS学习笔记

    http://www.zouyesheng.com/angular.html 关于AngularJS 关于本文档 开始的例子 依赖注入 作用域 数据绑定与模板 6.1. 数据->模板 6.2. ...