如何使用线程锁来提高多线程并发效率
时间:2022-04-24
本文章向大家介绍如何使用线程锁来提高多线程并发效率,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
今天对synchronized关键字的用法又有了更高一层的理解,特此记录一下。
一直对自己设计的多通道做单不是狠满意,并发效率低下。因为之前使用的锁一直是对象锁(this/类.class),这样则意味着每个线程抢到CPU执行权之后就会把整个类锁住,然后执行完被同步的全部代码后才释放锁,后面的线程才能执行同步代码,导致并发效率低下。还有一个问题就是:假如在某一时刻把整个类都锁住,那么这时在其他地方调用被锁住的这个类的其他方法,则要等到释放锁后才能调用。
模拟多窗口售票系统:
1 /**
2 * 多线程售票案例:
3 */
4 public
5 class SellTicket {
6
7 private static final Logger logger = LoggerFactory.getLogger(SellTicket.class);
8
9 public static void main(String[] args) {
10 MyThread unit = new MyThread(); //售票线程单元
11 //六个售票窗口开始同时售票5000张
12 logger.info("开始售票:{}=======================");
13 new Thread(unit,"【窗口一】").start();
14 new Thread(unit,"【窗口二】").start();
15 new Thread(unit,"【窗口三】").start();
16 new Thread(unit,"【窗口四】").start();
17 new Thread(unit,"【窗口五】").start();
18 new Thread(unit,"【窗口六】").start();
19 }
20 }
21
22 /**
23 * 创建线程单元:一个线程单元模拟一个售票窗口进行售票,每执行一次售出票数+1。
24 */
25 class MyThread implements Runnable{
26
27 private static Object lock = new Object(); //静态锁
28 private int votes = 1; //日预售票数起点
29
30 //售票
31 @Override
32 public void run() {
33 while(true){
34 //1、用lock静态所把锁的粒度缩小,提高并发效率。
35 //2、synchronized (MyThread.class): 把整个类锁住,这样很糟糕并且效率低下。比如调用其他方法,也要等得到锁才能继续做。
36 synchronized (lock) { //同步锁:保证在同一时刻最多只有一个线程单元进行售票
37 if (votes > 5000) {
38 //日票数已售完
39 break;
40 }
41 System.out.println(Thread.currentThread().getName()+"成功预订"+votes+"票");
42 votes++;
43 }
44 }
45 }
46 }
- WordPress免插件生成完整站点地图(sitemap.xml)的php代码
- Go语言常用字符串处理方法实例汇总
- 硬盘故障时如何强制关机:Input/output error
- 举例讲解Go语言中函数的闭包使用
- 实现WordPress提交评论的时删除该页面的WP-Super-Cache缓存的方法
- php自动生成百度开放适配PC页-手机页pattern对应关系sitemap.xml
- Linux系统最大文件打开数优化,解决Too many open files报错
- 【Dev Club 分享】安卓单元测试:What, Why and How
- WordPress记住评论用户信息的js版本,直接操作cookie无视缓存
- 禁止百度转码和百度快照缓存的META声明
- 单机MySQL数据库优化推荐的编译安装参数
- Linux网络实时流量监测工具iftop的安装使用
- Golang学习--GroupCache的使用
- 基于 Webpack & Vue & Vue-Router 的 SPA 初体验
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- redis实战第十五篇 redis cluster的批处理中ask重定向解决方案
- 干货 | Elasticsearch 运维实战常用命令清单
- 备战秋招-面经篇-[二十二]
- 快速上手Spring-Data-Redis
- Lua 5.1 参考手册
- 图文详解k8s自动化持续集成之GitLab CI/CD
- Harbor v2.0 镜像回收那些事
- redis实战第十四篇 redis cluster ask重定向
- Go命令官方指南【原译】
- 详解:如何监控小程序异常及处理错误?
- redis实战第十三篇 jedis连接redis cluster
- 哈工大李治军操作系统课程实验环境搭建
- 我用 OpenGL 实现了那些年流行的相机滤镜
- 使用minikube安装kubernetes和dashboard
- FFmpeg + OpenGLES 实现视频解码播放和视频滤镜