Java多线程之同步锁-lock详解
作者:小虚竹and掘金 发布时间:2023-12-16 14:40:08
标签:Java,同步锁
一、题目描述
题目:
同步锁出现的目的就是为了解决多线程安全问题。
同步锁的几种方式
synchronized
1、同步代码块
2、同步方法
jdk1.5后
3、lock锁:用lock()上锁,unlock()释放锁
实现:重现窗口售票多线程问题,并用lock锁解决。
二、解题思路
重现窗口售票多线程问题:
新创建类:LockDemo1
在main方法中,新创建三个线程,一起启动这三个线程。
新创建内部类:Ticket , Ticket implements Runnable
Ticket中每0.2秒卖一张票,用--i
使用lock锁:
新创建类:LockDemo2
在main方法中,新创建三个线程,一起启动这三个线程。
新创建内部类:Ticket , Ticket implements Runnable
在这段逻辑之前上锁,逻辑结束后释放锁 要把释放锁放在finally里
Ticket中每0.2秒卖一张票,用--i
lock锁相比于synchronized的好处是 灵活 ,可由研发人员自行控制加锁和解锁的时机。
三、代码详解
LockDemo1
/**
* Description: 重现窗口售票多线程问题
*
* @author xiaoxuzhu
* @version 1.0
*
* <pre>
* 修改记录:
* 修改后版本 修改人修改日期修改内容
* 2022/5/15.1 xiaoxuzhu2022/5/15 Create
* </pre>
* @date 2022/5/15
*/
public class LockDemo1 {
public static void main(String[] args) {
Ticket ticket = new Ticket();
new Thread(ticket, "1号窗口").start();
new Thread(ticket, "2号窗口").start();
new Thread(ticket, "3号窗口").start();
}
static class Ticket implements Runnable {
private int tick = 100;
@Override
public void run() {
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tick > 0) {
System.out.println(Thread.currentThread().getName() + "完成售票,余票是:" + --tick);
}
}
}
}
}
出现多线程问题:
LockDemo2
public class LockDemo2 {
public static void main(String[] args) {
Ticket ticket = new Ticket();
new Thread(ticket, "1号窗口").start();
new Thread(ticket, "2号窗口").start();
new Thread(ticket, "3号窗口").start();
}
static class Ticket implements Runnable {
private int tick = 100;
//创建锁
private Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
//上锁
lock.lock();
try {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tick > 0) {
System.out.println(Thread.currentThread().getName() + "完成售票,余票是:" + --tick);
}
}finally {
lock.unlock();
}
}
}
}
}
来源:https://juejin.cn/post/7151202086519537700


猜你喜欢
- 以下是SpringBoot项目中的常用配置类、jar包坐标等通用配置pom文件<!-- --><!-- 自定义配置文件
- 在.NET FrameWork中有多个Timer,那么怎么根据实际情况进行选择确实是一个问题。总体而言,计时器共有以下四种:多线程计时器:1
- 排列组合是常见的数学问题,本文就以完整实例形式讲述了C#实现排列组合算法的方法。分享给大家供大家参考之用。具体方法如下:首先,数学中排列组合
- 一、项目概述之前有不少粉丝私信我说,能不能用Android原生的语言开发一款在手机上运行的游戏呢?说实话,使用java语言直接开发游戏这个需
- 简单说一下(定义)什么是原型模式:原型模式是用于创建重复的对象,同时又能保证性能。用一个已经创建的实例作为原型,通过复制该原型对象来创建一个
- 前面文章讲解了Android的蓝牙基本用法,本文讲得深入些,探讨下蓝牙方面的隐藏API。用过Android系统设置(Setting)的人都知
- //有何不足或者问题希望能够得到各位的多多指正,不胜感激import java.util.Scanner;/** *
- 本文实例讲述了Java Swing组件布局管理器之FlowLayout(流式布局)。分享给大家供大家参考,具体如下:FlowLayout应该
- 一、检查数组是否包含某个值的方法使用Listpublic static boolean useList(String[] arr, Stri
- 这篇文章主要介绍了SpringBoot路径映射实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要
- 通常的函数调用 一个通常的函数调用的例子://自行包含头文件void MyFun(int x); //此
- 通过java代码规范来优化程序,优化内存使用情况,防止内存泄露可供程序利用的资源(内存、CPU时间、网络带宽等)是有限的,优化的目的就是让程
- Java调用Linux系统命令有时候,我们在使用Java做一些操作时,可能性能上并不能达到我们满意的效果,就拿最近工作中的遇到的一个场景来说
- 环境:apache-tomcat-8.5.15jdk1.8.0_172IDEA建立一个maven-webapp项目:Create New P
- 前言Genymotion 来自于 AndroVM 这个开源项目,基于 x86 和 VirtualBox,支持 OpenGL 加速,可以用于
- 好多时候,我们都需要知道某些目录下的文件什么时候被修改、删除过等,如果能用miniFilter驱动过滤来做的话当然是最好不过了,这是内核级别
- 我就废话不多说了,大家还是直接看代码吧~List<Order> list = new ArrayList<User>
- 在 Servlet/Jsp 项目中,如果涉及到系统任务,例如在项目启动阶段要做一些数据初始化操作,这些操作有一个共同的特点,只在项目启动时进
- 1.场景线程池使用DiscardOldestPolicy拒绝策略,阻塞队列使用ArrayBlockingQueue,发现在某些情形下对于得到
- 介绍今天我们将研究java中的Builder模式。Builder 设计模式是一种创造性的设计模式,如工厂模式和抽象工厂模式。当Object包