java多线程--6 死锁问题 锁Lock
java多线程--6 死锁问题 锁Lock
死锁问题
多个线程互相抱着对方需要的资源,然后形成僵持
死锁状态
package com.ssl.demo05;
public class DeadLock {
public static void main(String[] args) {
Makeup g1 = new Makeup(0,"灰");
Makeup g2 = new Makeup(1,"红");
g1.start();
g2.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
//化妆
class Makeup extends Thread{
//资源只有一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice; //选择
String girlName; //使用化妆品的人
Makeup(int choice,String girlName){
this.choice = choice;
this.girlName = girlName;
}
@Override
public void run() {
//化妆
try {
makeup();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//化妆,互相持有对方的锁
private void makeup(){
if (choice==0){
synchronized (lipstick){//获得口红的锁
System.out.println(this.girlName+"获得口红的锁");
try {
Thread.sleep(1000);
} catch (Exception e) {
throw new RuntimeException(e);
}
synchronized (mirror){ //1s 后获得镜子
System.out.println(this.girlName+"获得镜子的锁");
}
}
}else {
synchronized (mirror){//获得镜子
System.out.println(this.girlName+"获得镜子的锁");
try {
Thread.sleep(2000);
} catch (Exception e) {
throw new RuntimeException(e);
}
synchronized (lipstick){ //2s 获得口红
System.out.println(this.girlName+"获得口红的锁");
}
}
}
}
}
去除死锁
不要锁中锁
package com.ssl.demo05;
public class DeadLock {
public static void main(String[] args) {
Makeup g1 = new Makeup(0,"灰");
Makeup g2 = new Makeup(1,"红");
g1.start();
g2.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
//化妆
class Makeup extends Thread{
//资源只有一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice; //选择
String girlName; //使用化妆品的人
Makeup(int choice,String girlName){
this.choice = choice;
this.girlName = girlName;
}
@Override
public void run() {
//化妆
try {
makeup();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//化妆,互相持有对方的锁
private void makeup(){
if (choice==0){
synchronized (lipstick){//获得口红的锁
System.out.println(this.girlName+"获得口红的锁");
try {
Thread.sleep(1000);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
synchronized (mirror){ //1s 后获得镜子
System.out.println(this.girlName+"获得镜子的锁");
}
}else {
synchronized (mirror){//获得镜子
System.out.println(this.girlName+"获得镜子的锁");
try {
Thread.sleep(2000);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
synchronized (lipstick){ //2s 获得口红
System.out.println(this.girlName+"获得口红的锁");
}
}
}
}
产生死锁的四个必要条件
- 互斥条件: 一个资源每次只能被一个进程使用。
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得的资源,在未使用之前,不能强行剥夺。
- 循环等待条件:若干个进程之间形成一种头尾相接的循环等待资源关系。
Lock锁 JDK5开始
- 从JDK5开始,通过显示定义同步锁对象来实现同步。同步锁使用Lock对象充当。
- java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。
- ReentrantLock(可重入锁)类实现了Lock,它拥有与synchronized 相同的并发性和内存语意,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显式加锁、释放锁。
package com.ssl.demo05;
import java.util.concurrent.locks.ReentrantLock;
//测试Lock锁
public class TestLock {
public static void main(String[] args) {
TestLock2 testLock2 = new TestLock2();
new Thread(testLock2).start();
new Thread(testLock2).start();
new Thread(testLock2).start();
}
}
class TestLock2 implements Runnable{
int ticketNums = 10;
//定义Lock锁
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true){
try{
lock.lock(); //加锁
if (ticketNums >0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(ticketNums--);
}else{
break;
}
}finally {
//解锁
lock.unlock();
}
}
}
}
- 使用顺序
- Lock > 同步代码块 > 同步方法。
java多线程--6 死锁问题 锁Lock的更多相关文章
- “全栈2019”Java多线程第二十七章:Lock获取lock/释放unlock锁
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Java多线程专题5: JUC, 锁
合集目录 Java多线程专题5: JUC, 锁 什么是可重入锁.公平锁.非公平锁.独占锁.共享锁 可重入锁 ReentrantLock A ReentrantLock is owned by the ...
- Java多线程6:Synchronized锁代码块(this和任意对象)
一.Synchronized(this)锁代码块 用关键字synchronized修饰方法在有些情况下是有弊端的,若是执行该方法所需的时间比较长,线程1执行该方法的时候,线程2就必须等待.这种情况下就 ...
- Java多线程5:Synchronized锁机制
一.前言 在多线程中,有时会出现多个线程对同一个对象的变量进行并发访问的情形,如果不做正确的同步处理,那么产生的后果就是“脏读”,也就是获取到的数据其实是被修改过的. 二.引入Synchronized ...
- Java多线程学习(六)Lock锁的使用
系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...
- java多线程(死锁,lock接口,等待唤醒机制)
一.Lock接口 常用方法 Lock提供了一个更加面对对象的锁,在该锁中提供了更多的操作锁的功能. 使用Lock接口,以及其中的lock()方法和unlock()方法替代同步,对电影院卖票案例中Tic ...
- java 多线程总结篇4——锁机制
在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制.Java提供了多种多线程锁机制的实现方式,常见的有synchronized.ReentrantLock.Semaphore. ...
- JAVA多线程提高八:线程锁技术
前面我们讲到了synchronized:那么这节就来将lock的功效. 一.locks相关类 锁相关的类都在包java.util.concurrent.locks下,有以下类和接口: |---Abst ...
- JAVA多线程学习十一-线程锁技术
前面我们讲到了synchronized:那么这节就来将lock的功效. 一.locks相关类 锁相关的类都在包java.util.concurrent.locks下,有以下类和接口: |---Abst ...
- 【java多线程】ConCurrent并发包 - Lock详解
synchronized的缺陷 我们知道,可以利用synchronized关键字来实现共享资源的互斥访问. Java 5在java.util.concurrent.locks包下提供了另一种来实现 ...
随机推荐
- mybatis-generator 生成实体类,表字段类型有text,longtext,生成**WithBLOBs解决办法
modeType="flat" 其他参数请查询文档http://www.youbiji.cn/doc/mybatis/xml-table.html
- Delphi中KeyPress、KeyUp、keydown事件区别
KeyPress: 当用户按下键盘上的字符键(字母,数字) 会触发该事件,功能键则不会(F1-F12,Ctrl,Alt,Shift) KeyUp: 当按下键盘上的按键松开时,会触发OnKeyUp事件( ...
- mysql的隔离级别以及存储引擎
一.隔离级别 1.可序列化:(SERIALIZABLE):如果隔离级别为序列化,则用户之间通过一个接一个顺序地执行当前的事务,这种隔离级别提供了事务之间最大限度的隔离. 2.可重复读(REPEATAB ...
- Debug --> wireshark中的lua插件使用
一.使用Lua脚本对pcap文件按流进行存储 https://zhuanlan.zhihu.com/p/35188803 二.使用tshark对pcap报文进行批量切流 https://blog.cs ...
- error: You must be logged in to the server (Unauthorized) 问题处理
故障现象: 执行kubectl 命令时: 提示"error: You must be logged in to the server (Unauthorized)" 分析: 权限问 ...
- C语言初级阶段7——指针4
C语言初级阶段7--指针4 结构体指针 1.概念:所谓的结构体指针就是指向结构体变量的指针,一个结构体变量的起始地址就是这个结构体变量的指针.如果把一个结构体变量的其实地址存放在一个指针变量中,那么这 ...
- react 微信h5跳转小程序
componentDidMount() { this.getWxConfig() } getWxConfig () { // 请求后台接口拿到 data信息 wx.config({ debug: fa ...
- QT网络编程【二】【Socket】
1.QT中添加socket 库的相关操作 2.正常c++11 VS2019使用socket库的操作 3.winsock2 与 sys/socket.h的区别? 4.WinSock2 的基本操作? 详细 ...
- java学习笔记(四)变量
局部变量,必须声明和初始化值: 实列变量,从属于对象:如果不自行初始化,这个类型的默认值,数值类型,0,0.0 布尔值 默认为false 除了基本类型下,其余的默认值都是null 如 变量类型 ...
- kafka 学习
https://kafka.apache.org/quickstart C:\W_O_R_K\kafka_2.12-2.2.0\kafka_2.12-2.2.0\bin\windows\zookeep ...