高并发下Java多线程编程基础

摘要: Java线程同步与异步 线程池 无锁化的实现方案 分布锁的实现方案 分享的目的: 进一步掌握多线程编程和应用的技巧,希望对大家在平时的开发中应对高并发编程有所帮助 Java线程同步与异步 1. 同步相关的方法有 wait, notify, notifyAll 2.

Java线程同步与异步

线程池

无锁化的实现方案

分布锁的实现方案

分享的目的:

进一步掌握多线程编程和应用的技巧,希望对大家在平时的开发中应对高并发编程有所帮助

Java线程同步与异步

1. 同步相关的方法有

wait, notify, notifyAll

2. 关键字

synchronized

3. JDK锁的框架

AQS (AbstractQueuedSynchronizer)

4. AQS的实现类

java.util.concurrent.locks.ReentrantLock
java.util.concurrent.locks.ReentrantReadWriteLock
java.util.concurrent.CountDownLatch
java.util.concurrent.Semaphore

5. 例子——两个线程交替打印出100以内的奇数和偶数

主程序:

image.png
image.png

输出结果示例:

image.png
...
...
...
image.png

思考:

读者可以用两种其它方法实现,加深自己对Java线程同步和互斥的理解
用 ReentrantLock?
还是用wait和notify ?

线程池

作用:

控制线程并发数量,一般用在控制单机并发度上, 也是实现流控的一种方案;

实现原理:

1. 参数含义

corePoolSize: 核心线程的数量, 在CPU密集型和IO密集型的任务中,这个参数的设置不太一样:

在CPU密集型的应用中:

通常这个参数被设置为: 机器cpu核数-1, 例如机器有4个核,这个参数就被设置为3, 这样做的即兼顾了最大的并发度,又兼顾了其它非重要的核心任务的执行;

在IO密集的任务中:

通常这个参数被设置为机器cpu核数*(1.5 - 3),具体情况还需要根据实际业务情况进行压测比较,然后再给出最优的值;
maximumPoolSize: 最大核心线程的数量
poolSize: 当前线程的数量

当用户向线程池中新提交一个线程的时候,会有如下情况:

情况1.

如果当前线程池中线程的数量小于corePoolSize, 就会创建一个新的线程, 并添加到线程池中;

情况2.

如果当前线程池中线程的数量等于corePoolSize, 并且等待队列中还没有满,则把当前用户添加的线程对象放在等待队列中;

情况3.

如果当前线程池中线程的数量大于等于corePoolSize并且小于maximunPoolSize,并且等待队列已经满,则创建一个新的线程,并添加到线程池中;

情况4.

如果当前线程池中线程的数量等于maximunPoolSize, 则会根据线程创建线程时候的拒绝策略,进行相应的处理;

2. java线程对象中run方法和start方法的区别:

2.1 线程对象直接调用run方法,JVM是不会有感知,是不会直接产生一个新的线程, 此时程序运行的方式依然是串行的;
2.2 线程对象直接调用start方法,JVM才会有感知,会产生一个新的线程, 此时才会产生并发多线程;
线程池正是充分利用了run方法和start的区别来实现线程的复用;

3. 线程池的核心代码

下面均是以jdk1.6的线程池的源码,jdk1.7和jdk1.8线程池实现在上有些变化,但核心思想不变,有兴趣可以自己去研究

提交线程的核心代码:

image.png

执行用户任务的核心代码:

image.png

无锁化的实现方案

用线程池的方案

1. netty的reactor线程模型,参考netty官方或网上相关的资料

2. 异地机房数据库之间的数据同步:

用表名+主键名做hash ,hash值相同的记录被写到同一个Kafka的Partition中去,假设一个Partition用一个线程进行消费, 这样不同线程之间写入目标数据库的时候,就不会存在数据库行锁的竞争关系,间接实现了无锁化的操作, 即线程之间并行,线程内部串行, 如下图所示;
image.png

用CAS的命令

1. JDK中各种类型值的原子操作

AtomicInteger
AtomicLong
AtomicBoolean

2. jdk中各种锁的实现, 本质也是volitate变量+CAS

java.util.concurrent.locks.ReentrantLock
java.util.concurrent.Semaphore
java.util.concurrent.CountDownLatch

分布锁的实现方案

1. tair

incr和decr操作,相当于是乐观锁

2. Redis/memcache

setNx命令

3. Zookeeper

充分利用watcher机制,创建临时结点,谁创建成功,谁就获得当前的锁

4. 数据库:利用数据库的行锁

// 加锁SQL
update trade_base set status = 1 where trade_no=“XXX” and status = 0;
// 解锁SQL
update trade_base set status = 0 where trade_no=“XXX” and status = 1;
注意trade_base表上一要有trade_no的列的唯一索引

当然具体用那种分布锁,还需要结合业务自身的需要,一般来说,在并发量不是别大,数据库完全可以扛得住的情况下,用数据库实现分布锁最快,最方便,而且性能的损失也非常地小;
当然现在很多场景下,都是分库分表,并且加锁和解锁分别都只影响一行,对数据库来说,加锁和解锁的 sql也是非常轻量的sql操作,因此在性能损失上不用过多的担心;

原文链接

本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/521385.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

deebot扫地机器人怎么清洁_扫地机器人清洁力拼杀,科沃斯机器人DEEBOT N3与小米1S对比评测...

“偷懒是第一生产力”,这句看似玩笑的话细细品味起来似乎还是有点道理,扫地机器人产业的逐渐兴盛又一次验证科技改变人们的生活方式。我自己生活中很少有时间去清扫地面,而且我是个很容易制造垃圾的人,几天不扫家里就脏乱的无法直…

机票分享第一篇 机票由何而来

要: 遥想05年刚加入飞猪,有同学问我机票搜索是怎么做的,一时间不知如何回答。转眼三年过去,为了给自己一个交代,抽时间把所负责的业务、系统、心得加以总结,才有了这几篇机票分享的文章。由于所用的技术、架…

java 获取ip地址_老杜带你学Java【第二课】

上期链接:老杜带你学Java【第一课】01写在前面欢迎来到杜老师的「零基础学Java」课堂~今后,我们就是Java软件工程师了。(此处应该有掌声???)本专题为《零基础学Java》专题,将带你学习2020年全新Java零基础教程,由杜老师亲自录制…

【光说不练假把式】今天说一说Kubernetes 在有赞的实践

戳蓝字“CSDN云计算”关注我们哦!作者 | 木鱼 on基础保障责编 | 阿秃一、背景我们为什么选择 Kubernetes?因为 Kubernetes 几乎支持所有的容器业务类型,包括无状态应用、有状态应用、任务型和 Daemonset,Kubernetes 也逐渐成为容…

Apache旗下顶级开源盛会 HBasecon Asia 2018将于8月在京举行

摘要: 作为Apache基金会旗下HBase社区的顶级用户峰会,HBaseCon大会是Apache HBase™官方从2012年开始发起和延续至今的技术会议,先后在美国加州、日本东京和中国深圳等地举办,得到了Google、Facebook、雅虎和阿里巴巴等众多全球顶…

r语言查找是否存在空值_关于R包安装你知道多少?

在R语言的学习过程中离不了各种R包的安装与使用,要使用某个R包首先得学会如何安装该R包。对于R包的安装你知道的有多少?你知道如何指定安装路径吗?为何你每次重新打开R绘画都需要重新安装R包?今天小编带你详细理解install.package…

深入理解JAVA虚拟机学习笔记(一)JVM内存模型

摘要: 上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了。这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状…

oracle schema_了解Oracle备份恢复的知识

Oracle架构体系警报日志(alter log):一个文本日志文件,记录数据库的错误和状态信息,通常情况下,警报日志位于后台转存目标目录中,该目录有数据库参数DIAFNOSTIC_DEST定义的,其中警报日志的格式为alter.log。…

美部长施压堵华为,遭印度电信巨头现场驳斥 ;WhatsApp被曝漏洞:仅凭一张GIF动图黑客便可接管账户……...

关注并标星星CSDN云计算极客头条:速递、最新、绝对有料。这里有企业新动、这里有业界要闻,打起十二分精神,紧跟fashion你可以的!每周三次,打卡即read更快、更全了解泛云圈精彩newsgo go go 每周三次,打卡即…

实现Chrome Devtools调试JavaScript V8引擎

摘要: 最近开发小程序JavaScript的运行时,通过在客户端嵌入JavaScript V8引擎来实现。前端同学需要调试JavaScript代码,正好Chrome浏览器的Devtools是与V8的Inspector调试协议是一脉相承的,理论上是可以使用Chrome Devtools调试Ja…

angular7.2构建包如何兼容ie_Python 小技巧:如何实现操作系统兼容性打包?

转自:Python猫有一个这样的问题:现要用 setuptools 把一个项目打包成 whl 文件,然后 pip install 在 Windows/Linux 两种操作系统上,但是该项目中有一些依赖库只有 Windows 上才有(例如 pywinauto、pywingui、pywinrm)&#xff0c…

阿里云ET工业大脑发布AI视觉产品“见远”:电池片、车辆、路面都能被“诊断”

摘要: 7月24日,阿里云ET工业大脑发布AI视觉产品“见远“,可以利用深度学习和图像处理算法,自动识别图像中的瑕疵、故障及其他目标物,大幅节省人力,提高产品生产效率及精度稳定性效果。 7月24日&#xff0c…

最后2天,BDTC 2019 早鸟票即将售罄,超强阵容及议题抢先曝光!

大会官网:https://t.csdnimg.cn/U1wA2019 年12月5-7 日,由中国计算机学会主办,CCF 大数据专家委员会承办,CSDN、中科天玑数据科技股份有限公司协办的 2019 中国大数据技术大会,将于北京长城饭店隆重举行。届时&#xf…

利用python做一个小游戏_如何使用python做一个简单的猜数字的小游戏

1 首先小编先打开IDLE,如下图:2 然后这里点击菜单栏的File,然后点击菜单"New File",如下图:3 然后我们就在idle中新建了一个python文件,如下图:4 在这里我们按照下图中代码输入到文件…

阿里HBase的数据管道设施实践与演进

摘要: 大数据生态下有着丰富多样的系统:流计算,数据存储,实时分析,离线计算,数据在各个异构系统之间的流转和加工而产生价值,高效的数据传输通道是大数据生态的重要一环。本文描述了阿里HBase团…

gradle官方文档_Spring Boot+Gradle+MyBatisPlus3.x搭建企业级的后台分离框架

你再主动一点点 我们就有故事了原文:toutiao.com/i68614564967402706041、技术选型解析器:FastJSON开发工具:JDK1.8 、Gradle、IDEA技术框架:SpringBoot 2.1.5.RELEASEORM技术:MyBatisPlus3.1.2数据库:My…

java random用法_JAVA面试题(1)

1.Java内部类和子类之间有什么区别?答案:内部类是指在一个外部类的内部再定义一个类,内部类对外部类有访问权限,可以访问类 中定义的所有变量和方法。子类是从父类(superclass)中继承的类,子类可以访问父类所有public和…

【不了解你就OUT了】云原生基本原则

戳蓝字“CSDN云计算”关注我们哦!作者 | 架构师技术联盟责编 | 阿秃云原生指的是一个敏捷的工程团队,遵循敏捷的研发原则,使用高度自动化的研发工具,开发基于云基础设施和服务的应用以满足快速变化的客户需求。这些应用采用弹性&…

如何降低90%Java垃圾回收时间?以阿里HBase的GC优化实践为例

摘要: GC一直是Java应用中讨论的一个热门话题,尤其在像HBase这样的大型在线存储系统中,大堆下(百GB)的GC停顿延迟产生的在线实时影响,成为内核和应用开发者的一大痛点。 过去的一年里,我们准备在Ali-HBase上突破这个被…

会不会导致内存泄漏_Java内存泄漏!为什么会泄漏?如何泄漏?怎么定位?

JVM应该可以算Java中最为核心的部分了,其中开箱即用的内存管理又是JVM中的核心组成部分。我们都知道JVM的内存管理具有垃圾回收功能(Java Garbage Collector),编码时只需要new而无需主动的释放(类似于C中的delete操作),所以Java中比较少出现内…