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+"获得口红的锁");
}
}
}
}

产生死锁的四个必要条件

  1. 互斥条件: 一个资源每次只能被一个进程使用。
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:进程已获得的资源,在未使用之前,不能强行剥夺。
  4. 循环等待条件:若干个进程之间形成一种头尾相接的循环等待资源关系。

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的更多相关文章

  1. “全栈2019”Java多线程第二十七章:Lock获取lock/释放unlock锁

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  2. Java多线程专题5: JUC, 锁

    合集目录 Java多线程专题5: JUC, 锁 什么是可重入锁.公平锁.非公平锁.独占锁.共享锁 可重入锁 ReentrantLock A ReentrantLock is owned by the ...

  3. Java多线程6:Synchronized锁代码块(this和任意对象)

    一.Synchronized(this)锁代码块 用关键字synchronized修饰方法在有些情况下是有弊端的,若是执行该方法所需的时间比较长,线程1执行该方法的时候,线程2就必须等待.这种情况下就 ...

  4. Java多线程5:Synchronized锁机制

    一.前言 在多线程中,有时会出现多个线程对同一个对象的变量进行并发访问的情形,如果不做正确的同步处理,那么产生的后果就是“脏读”,也就是获取到的数据其实是被修改过的. 二.引入Synchronized ...

  5. Java多线程学习(六)Lock锁的使用

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

  6. java多线程(死锁,lock接口,等待唤醒机制)

    一.Lock接口 常用方法 Lock提供了一个更加面对对象的锁,在该锁中提供了更多的操作锁的功能. 使用Lock接口,以及其中的lock()方法和unlock()方法替代同步,对电影院卖票案例中Tic ...

  7. java 多线程总结篇4——锁机制

    在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制.Java提供了多种多线程锁机制的实现方式,常见的有synchronized.ReentrantLock.Semaphore. ...

  8. JAVA多线程提高八:线程锁技术

    前面我们讲到了synchronized:那么这节就来将lock的功效. 一.locks相关类 锁相关的类都在包java.util.concurrent.locks下,有以下类和接口: |---Abst ...

  9. JAVA多线程学习十一-线程锁技术

    前面我们讲到了synchronized:那么这节就来将lock的功效. 一.locks相关类 锁相关的类都在包java.util.concurrent.locks下,有以下类和接口: |---Abst ...

  10. 【java多线程】ConCurrent并发包 - Lock详解

    synchronized的缺陷   我们知道,可以利用synchronized关键字来实现共享资源的互斥访问. Java 5在java.util.concurrent.locks包下提供了另一种来实现 ...

随机推荐

  1. 从redis中取出数据并转成java对象

    1.//数据存入redis中 redisTemplate.opsForValue().set(loginame, JSON.toJSONString(users),1000,TimeUnit.SECO ...

  2. CCF 202006-2 稀疏向量

    #include <iostream> #include <bits/stdc++.h> #include <string> using namespace std ...

  3. C语言||一作业04

    作业头 这个作业属于哪个课程 https://edu.cnblogs.com/campus/zswxy/SE2020-3 这个作业要求在哪 https://edu.cnblogs.com/campus ...

  4. 随机生成不重复的几个数(Unity)

    using System.Collections.Generic; using UnityEngine; /// <summary> /// 随机数管理类 /// </summary ...

  5. 1vue模板语法

    <body> <div id="app1"> <div>{{msg}}</div> </div> <script ...

  6. 【Win11】电脑开机内存占用过高

    联想拯救者 Y7000P 1.Win+R打开运行输入"MdSched"   重启 2.Windows PowerShell(管理员)->并运行该命令 Disable-MMAg ...

  7. oracle 白名单作用及配置教程

    出于提高数据安全性等目地,我们可能想要对oracle的访问进行限制,允许一些IP连接数据库或拒绝一些IP访问数据库. 当然使用iptables也能达到限制的目地,但是从监听端口变更限制仍可生效.只针对 ...

  8. md文件使用说明

    md文件简单使用介绍 二级标题 三级标题 斜体文本 粗体文本 粗斜体文本 分隔线 删除号 带下划线 创建脚注格式类似这样 [1]. #include <iostream> using na ...

  9. heimaJava18_线程

    Java 线程 单线程 线程(thread)是一个程序内部的一条执行路径. main方法的执行其实就是一个单独的执行路径 程序中如果只有一条执行路径,那么这个程序就是单线程的程序 多线程 多线程是指从 ...

  10. 关于PLC的脉冲输出(S7-300)

    1.   关于脉冲输出 脉冲输出的方法有很多: 如果要产生占空比为50%的脉冲信号: ①     用S7-300PLC的时钟存储器 右键点击PLC,选中时钟存储器,默认存储字节为0. 各时钟存储器的周 ...