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包下提供了另一种来实现 ...
随机推荐
- iOS 高级面试题
面试题 iOS 基础题 分类和扩展有什么区别?可以分别用来做什么?分类有哪些局限性?分类的结构体里面有哪些成员? 讲一下atomic的实现机制:为什么不能保证绝对的线程安全(最好可以结合场景来说)? ...
- web测试:test过程中接口报错 "Object reference not set to an instance of an object."
"Object reference not set to an instance of an object." 对象引用未设置为对象的实例 可能原因: 1.参数类型传错,或少传参数 ...
- UNIT THREE
基础 (1) 内存以字节为单位,划分为若干个单元.(2) 计算机内数据存-取单位: ① 字节 (8bit) ② 字 (16bit) ③ 双字 (32bit) ④ 四字 (64bit) ds寄存器 DS ...
- IDEA初步使用Maven
Maven使用 Maven环境配置 下载maven,解压,放在一个没有中文的路径下 打开系统环境变量配置 添加MAVEN_HOME ,其路径为maven所在路径 E:\software\apache- ...
- Arrays.asList()的使用
JDK文档说明: @SafeVarargs public static <T> List<T> asList(T... a) 返回由指定数组支持的固定大小的列表(将返回的列表更 ...
- Spring系列之字段格式化-13
字段格式化 Spring 3 引入了一个方便的SPI,它为客户端环境的实现Formatter提供了一个简单而健壮的替代方 Formatter Formatter实现字段格式化逻辑的SPI . pack ...
- centos 挂载共享目录
共享目录://10.253.47.102/share/文件传递暂用 将共享路径挂载到centos /etc/fstab 添加一行配置,mount -a 生效
- Day1.无敌难受且成功
Markdown学习 标题 字体 ctrl+b.l.u.k加粗.斜体.下划线.超链接 引用 大于号+空格 分割线 三个*** ###都 图片 !+[]+() 英文输入法的符号 输入的图片路径可本地也要 ...
- 12.20linux学习第十九天
今天老刘开始讲第17章 使用iSCSI服务部署网络存储.第18章 使用MariaDB数据库管理系统和第19章 使用PXE+Kickstart无人值守安装服务,内容有点多. 7.1 iSCSI技术介绍 ...
- ant build 报 warning modified in the future
错误原因:在测试项目时,修改了系统时间,之后保存了文件,再将系统时间改回来,会报这个错误 解决方法:复制改过的文件到记事本,然后回退下文件,再将记事本的内容覆盖下文件,重新build下就可以了.