高并发下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以内的奇数和偶数
主程序:
输出结果示例:
...
...
...
思考:
读者可以用两种其它方法实现,加深自己对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线程池实现在上有些变化,但核心思想不变,有兴趣可以自己去研究
提交线程的核心代码:
执行用户任务的核心代码:
无锁化的实现方案
用线程池的方案
1. netty的reactor线程模型,参考netty官方或网上相关的资料
2. 异地机房数据库之间的数据同步:
用表名+主键名做hash ,hash值相同的记录被写到同一个Kafka的Partition中去,假设一个Partition用一个线程进行消费, 这样不同线程之间写入目标数据库的时候,就不会存在数据库行锁的竞争关系,间接实现了无锁化的操作, 即线程之间并行,线程内部串行, 如下图所示;
用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操作,因此在性能损失上不用过多的担心;
原文链接
本文为云栖社区原创内容,未经允许不得转载。
高并发下Java多线程编程基础相关推荐
- java多线程编程--基础篇
一.基本概念 a.操作系统中进程与线程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间, 一个进程中可以启动 ...
- java多线程编程基础
thread和runnable已经out了.取而代之的是callable<V>,它的结果存在future<V>中.后者有get对象可以阻塞并最终获得异步结果.FutureTas ...
- Java多线程编程实战指南+设计模式篇pdf
下载地址:网盘下载 随着CPU 多核时代的到来,多线程编程在充分利用计算资源.提高软件服务质量方面扮演了越来越重要的角色.而 解决多线程编程中频繁出现的普遍问题可以借鉴设计模式所提供的现成解决方案.然 ...
- java多线程基础视频_【No996】2020年最新 Java多线程编程核心基础视频课程
01.课程介绍.mp4 02.多线程编程基础-进程与线程.mp4 03.多线程编程基础-使用多线程-继承Thread类.mp4 04.多线程编程基础-使用多线程-实现Runnable接口.mp4 05 ...
- java多线程编程01---------基本概念
一. java多线程编程基本概念--------基本概念 java多线程可以说是java基础中相对较难的部分,尤其是对于小白,次一系列文章的将会对多线程编程及其原理进行介绍,希望对正在多线程中碰壁的小 ...
- Java多线程编程那些事:volatile解惑--转
http://www.infoq.com/cn/articles/java-multi-thread-volatile/ 1. 前言 volatile关键字可能是Java开发人员"熟悉而又陌 ...
- Java多线程编程模式实战指南(二):Immutable Object模式--转载
本文由本人首次发布在infoq中文站上:http://www.infoq.com/cn/articles/java-multithreaded-programming-mode-immutable-o ...
- Java多线程编程-(5)-使用Lock对象实现同步以及线程间通信
前几篇: Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-线程本地Th ...
- Java NIO编程基础
Java NIO编程基础 Java NIO 基本介绍 NIO的Buffer基本使用 NIO 和 BIO 的比较 NIO 三大核心原理示意图 缓冲区(Buffer) 基本介绍 Buffer 类及其子类 ...
最新文章
- w3 html网页元素,HTML Object 元素
- 使用Javascript创建XML文件
- How does a relational database work
- 基于Qt\C++实现的网络远程控制系统
- python安装scrapy框架命令_python爬虫中scrapy框架是否安装成功及简单创建
- [css] 标签、class和id选择器三者的区别是什么?分别在什么时候用?
- 论文浅尝 | 通过学习中间步骤的监督信号改进多跳知识库问答
- 1048 行 MySQL指令(经典)
- jQuery查找标签--选择器,筛选器,模态对话框, 左侧菜单栏
- FastDFS分布式文件系统
- vSphere 7 With Kubernetes系列01:随想
- CentOS7 安装 Mysql 服务
- 程序员更像艺术家 哪种状态更具创造性?
- Linux访问交换机FTP,华为交换机使用FTP查看下载文件
- 中国电信中兴 B860AV 1.1-T线刷及卡刷固件和刷机教程.zip
- 如何区分固态硬盘和机械硬盘
- react routers路由地址 F5刷新白屏
- matlab求信号的瞬时相位,phrase MATLAB中关于信号瞬时相位和瞬时频率的提取的代码 - 下载 - 搜珍网...
- C语言中scanf()函数中的是什么
- u盘虚拟启动cd linux,CDlinux制作U盘启动盘,打造自己的口袋系统
热门文章
- mysql5.7 xtrabackup_MySQL 5.7 基于GTID建立运行主库的从库-xtrabackup+mysqldump
- react 子传参父_react子父传参有几种方法?
- 算法与数据结构c语言版PPT,C语言算法与数据结构.ppt
- oracle数据库密码复杂度查询,Oracle11g R2创建PASSWORD_VERIFY_FUNCTION对应密码复杂度验证函数步骤...
- 扫一扫 移动端_移动端手机APP 身份证识别 手机扫一扫离线识别
- 红外倒车雷达原理图_硅光电倍增管 (SiPM) 直接飞行时间 (dToF) 激光雷达平台为工业测距应用提供现成的设计...
- 完美数:数学宝库中的一颗璀璨明珠
- 办学10年,进入全国前10名!这所神奇的高校,迎来10岁生日
- 3分钟了解物理学发展史
- 超级高铁Hyperloop进入新阶段,将在华盛顿破土动工!