12、synchronized和Lock的使用
1、多并发案例:
一个车站有三个窗口同时卖30张票,每个窗口都有40个人在排队买票,在多线程情况下,不加锁,线程不安全,导致卖票不准确
package com.example.Lock; /**
* 线程就是一个单独的资源类,没有任何附属的操作
*/
public class demo1 {
public static void main( String[] args )
{
//并发:多线程操作同一个资源类,把资源类丢入线程
Ticket ticket = new Ticket(); new Thread(() -> {
for(int i=0;i<40;i++){
ticket.sale();
}
},"A窗口").start(); new Thread(() -> {
for(int i=0;i<40;i++){
ticket.sale();
}
},"B窗口").start(); new Thread(() -> {
for(int i=0;i<40;i++){
ticket.sale();
}
},"c窗口").start();
}
} /**
* 资源类
*/
class Ticket{ //总票数
private int number = 30; //卖票
public void sale(){
if(number>0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"张票,剩余: "+number);
}
}
}
2、使用锁:
解决上面的线程不安全的问题,可以通过加锁的方式
(1)、方式一:synchronized关键字
使用synchronized,在卖票的方法加synchronized关键字,表示对是整个方法范围内对当前对象的加锁
//卖票
public synchronized void sale(){
if(number>0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"张票,剩余: "+number);
}
}
(2)、方式二:Lock接口
使用Lock,一共三步
——》创建锁
——》加锁
——》解锁
/**
* 资源类
*/
class Ticket{ //总票数
private int number = 30; //创建锁
Lock lock = new ReentrantLock(); //卖票
public void sale(){ //加锁
lock.lock(); try {
if(number>0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"张票,剩余: "+number);
}
} catch (Exception e) { }finally{
//解锁
lock.unlock();
} }
}
3、synchronized和Lock的区别:
(1)、synchronized是内置的Java关键字;Lock是一个接口
(2)、synchronized无法判断获取锁的状态;Lock可以
(3)、synchronized会自动释放锁;Lock必须手动释放锁,如果不释放,就会出现死锁
(4)、synchronized多个线程获取同一个锁,其中一个线程已经获取锁,但发生阻塞,其他线程就会一直等待;Lock不一定等待下去
(5)、synchronized是可重入锁,不可以中断的,非公平;Lock也是可重入锁,可以判断锁,默认非公平(可以设置公平)
(6)、synchronized适合锁少量代码同步;Lock适合锁大量同步代码
搜索
复制
12、synchronized和Lock的使用的更多相关文章
- 线程安全、数据同步之 synchronized 与 Lock
本文Demo下载传送门 写在前面 本篇文章讲的东西都是Android开源网络框架NoHttp的核心点,当然线程.多线程.数据安全这是Java中就有的,为了运行快我们用一个Java项目来讲解. 为什么要 ...
- 转:synchronized和LOCK的实现原理---深入JVM锁机制
JVM底层又是如何实现synchronized的? 目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug ...
- JAVA中synchronized和lock详解
目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug Lea.本文并不比较synchronize ...
- Java synchronized和 Lock 的区别与用法
在分布式开发中,锁是线程控制的重要途径.Java为此也提供了2种锁机制,synchronized和lock.做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方. ...
- 关于synchronized和Lock
原文链接:关于volatile关键字解析,synchronized和Lock参考 深入浅出,解释的非常清楚,有条理~~~ 以下为转载内容: Java并发编程:volatile关键字解析 volatil ...
- 【转载】synchronized 与 Lock 的那点事
最近在做一个监控系统,该系统主要包括对数据实时分析和存储两个部分,由于并发量比较高,所以不可避免的使用到了一些并发的知识.为了实现这些要求,后台使用一个队列作为缓存,对于请求只管往缓存里写数据.同时启 ...
- synchronized 与 Lock 的那点事
最近在做一个监控系统,该系统主要包括对数据实时分析和存储两个部分,由于并发量比较高,所以不可避免的使用到了一些并发的知识.为了实现这些要求,后台使用一个队列作为缓存,对于请求只管往缓存里写数据.同时启 ...
- Java多线程编程(四)—浅谈synchronized与lock
一.共享资源竞争问题 在Java语言的并发编程中,由于我们不知道线程实际上在何时运行,所以在实际多线程编程中,如果两个线程访问相同的资源,那么由于线程运行的不确定性便会在这种多线程中产生访问错误.所以 ...
- synchronized和lock比对
前言:在上面的博客说了synchronized的一些用法,下面我们再来看看lock,这个出现频率也是非常高的一个. 1:获取Lock锁的几种方式 前面说了synchronized有锁对象和锁类对象,当 ...
随机推荐
- vue禁用浏览器返回键
mounted () { // 禁用浏览器返回键 history.pushState(null, null, document.URL); window.addEventListener('popst ...
- 魔改xxl-job,彻底告别手动配置任务!
原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是Hydra. xxl-job是一款非常优秀的任务调度中间件,轻量级.使用简单.支持分布式等优点,让它广泛应用在我们的项目中,解 ...
- 绝杀processOn,这款UML画图神器,阿里字节都用疯了,你还不知道?
大家好,我是陶朱公Boy,又和大家见面了. 前言 在文章开始前,想先问大家一个问题,大家平时在项目需求评审完后,是直接开始编码了呢?还是会先写详细设计文档,后再开始进行编码开发? ☆现实 这个时候可能 ...
- 【C++】spdlog光速入门,C++logger最简单最快的库
参考文档:https://spdlog.docsforge.com/master/ spdlog简介 Very fast, header only, C++ logging library. 一个he ...
- 代码块及final关键字的使用
1.代码块的作用:用来初始化类.对象 2.代码块如果有修饰的话,只能使用static. 3.分类:静态代码块 vs 非静态代码块 4.静态代码块 内部可以有输出语句 随着类的加载而执行,而且只执行一次 ...
- 驱动开发:Win10内核枚举SSDT表基址
三年前面朝黄土背朝天的我,写了一篇如何在Windows 7系统下枚举内核SSDT表的文章<驱动开发:内核读取SSDT表基址>三年过去了我还是个单身狗,开个玩笑,微软的Windows 10系 ...
- JUC(10)深入理解CAS和ABA
文章目录 1.CAS 2.原子引用解决ABA问题,版本号.修改后,可以看到 1.CAS package com.cas; import java.util.concurrent.atomic.Atom ...
- 常用排序算法(C语言)
1.冒泡排序 void BubbleSort(int a[],int len) {int tmp; for (int i=0; i<n-1; i++) { int flag = FALSE; f ...
- Java 8 Time API
Java 8 系列文章 持续更新中 日期时间API 也是Java 8重要的更新之一,Java从一开始就缺少一致的日期和时间方法,Java 8 Date Time API是Java核心API的一个非常好 ...
- SpringBoot 过滤器和拦截器
过滤器 实现过滤器需要实现 javax.servlet.Filter 接口.重写三个方法.其中 init() 方法在服务启动时执行,destroy() 在服务停止之前执行. 可用两种方式注册过滤器: ...