JDK 并发包

3.1 多线程的同步协助:同步控制

3.1.1 synchronized 扩展功能:重入锁

jdk1.5之前重入锁ReentrantLook性能好于synchronized, 但jdk1.6 开始优化ReentrantLook, 现在二者的性能相差不大。

/**

* @author ChengBing Han

* @date 21:50 2018/6/23

* @description

*/

public class ReentrantLockTest {

static ReentrantLock reentrantLock = new ReentrantLock();

static final Object obj = new Object();

public static void main(String[] args) throws InterruptedException {

final Thread t1 = new Thread(new Runnable() {

public void run() {

System.out.println("T1 lock1");

reentrantLock.lock();

System.out.println("T1 lock2");

reentrantLock.lock();

System.out.println("T1 unlock1");

reentrantLock.unlock();

System.out.println("T1 unlock2");

reentrantLock.unlock();

}

});

final Thread t2 = new Thread(new Runnable() {

public void run() {

synchronized (obj){

System.out.println("t2 lock1");

synchronized (obj){

System.out.println("t2 lock2 ");

}

}

System.out.println("t2 end");

}

});

System.out.println("lock============");

t1.start();

Thread.sleep(1000);

System.out.println("syschronized==================");

t2.start();

}

}

输出:

lock============

T1 lock1

T1 lock2

T1 unlock1

T1 unlock2

syschronized==================

t2 lock1

t2 lock2

t2 end

中断响应

public class Interrupted implements Runnable {

private Integer state = 0;

public Interrupted() {

}

public Interrupted(Integer state) {

this.state = state;

}

static ReentrantLock reentrantLock1 = new ReentrantLock();

static ReentrantLock reentrantLock2 = new ReentrantLock();

public void run() {

try {

if(state == 1) {

reentrantLock1.lockInterruptibly();

System.out.println("state1===lock1");

Thread.sleep(1000);

reentrantLock2.lockInterruptibly();

System.out.println("state1===lock2");

}else if(state == 2){

reentrantLock2.lockInterruptibly();

System.out.println("state2===lock2");

Thread.sleep(1000);

reentrantLock1.lockInterruptibly();

System.out.println("state2===lock1");

}

} catch (InterruptedException e) {

e.printStackTrace();

}finally {

if(reentrantLock1.isHeldByCurrentThread()){

reentrantLock1.unlock();

}

if(reentrantLock2.isHeldByCurrentThread()){

reentrantLock2.unlock();

}

}

}

public static void main(String[] args) throws InterruptedException {

final Interrupted r1 = new Interrupted(1);

final Interrupted r2 = new Interrupted(2);

final Thread t1 = new Thread(r1);

final Thread t2 = new Thread(r2);

t1.start();

Thread.sleep(100);

t2.start();

Thread.sleep(5000);

t2.interrupt();

}

}

输出

state1===lock1

state2===lock2

java.lang.InterruptedException

at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)

at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)

at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)

at com.hcb.thread.c3_1_retrantlookinterrupted.Interrupted.run(Interrupted.java:39)

at java.lang.Thread.run(Thread.java:748)

state1===lock2

锁申请等待限时

一个锁只能锁住某个时间段

public class TimeLock implements Runnable{

static ReentrantLock reentrantLock = new ReentrantLock();

public void run() {

try {

if(reentrantLock.tryLock(3, TimeUnit.SECONDS)){

System.out.println(Thread.currentThread().getName() + " run");

Thread.sleep(6000);

}else {

System.out.println(Thread.currentThread().getName() + "getLock failed");

}

} catch (InterruptedException e) {

e.printStackTrace();

}finally {

//注意finally 这里释放锁的方式

if(reentrantLock.isHeldByCurrentThread()){

reentrantLock.unlock();

}

}

}

public static void main(String[] args) throws InterruptedException {

final TimeLock r1 = new TimeLock();

final Thread thread1 = new Thread(r1);

thread1.setName("t1");

thread1.start();

Thread.sleep(100);

final TimeLock r2 = new TimeLock();

final Thread thread2 = new Thread(r2);

thread2.setName("t2");

thread2.start();

}

}

公平锁

public class FairLock {

//构造函数为true,表示公平

static ReentrantLock reentrantLock = new ReentrantLock(true);

public static class ThreadFair implements Runnable {

public void run() {

while (true) {

try {

reentrantLock.lockInterruptibly();

System.out.println(Thread.currentThread().getName() + " run ");

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

if (reentrantLock.isHeldByCurrentThread()) {

reentrantLock.unlock();

}

}

}

}

}

public static void main(String[] args) {

final ThreadFair threadFair = new ThreadFair();

final Thread fairThread1 = new Thread(threadFair, "fairThread1");

final ThreadFair threadFair2 = new ThreadFair();

final Thread fairThread2 = new Thread(threadFair2, "fairThread2");

fairThread1.start();

fairThread2.start();

}

}

output:

fairThread1 run

fairThread2 run

fairThread1 run

fairThread2 run

fairThread1 run

fairThread2 run

fairThread1 run

fairThread2 run

fairThread1 run

fairThread2 run

fairThread1 run

fairThread2 run

fairThread1 run

fairThread2 run

重入锁的condition条件

Condition条件类似与wait,notify方法

备注:Condition的使用注意

1、必须在lock.lock()

和lock.singXX中使用 await/singXX

2、方法名是await 不是wait,wait 是object的方法

public class ConditionLock {

static ReentrantLock reentrantLock = new ReentrantLock();

static Condition condition = reentrantLock.newCondition();

static class ConditionLockThread implements Runnable {

public void run() {

reentrantLock.lock();

try {

System.out.println(Thread.currentThread().getName() + " wait...");

//方法是await不是object的wait

condition.await();

System.out.println(Thread.currentThread().getName() + " end wait...");

} catch (InterruptedException e) {

e.printStackTrace();

}finally {

if(reentrantLock.isHeldByCurrentThread()){

reentrantLock.unlock();

}

}

}

}

public static void main(String[] args) throws InterruptedException {

final ConditionLockThread conditionLockThread1 = new ConditionLockThread();

final Thread thread1 = new Thread(conditionLockThread1, "ConditionLockThread1");

final ConditionLockThread conditionLockThread2 = new ConditionLockThread();

final Thread thread2 = new Thread(conditionLockThread2, "ConditionLockThread2");

thread1.start();

thread2.start();

Thread.sleep(1000);

//必须在 lock.lock/unlock 中间使用

reentrantLock.lock();

condition.signalAll();

reentrantLock.unlock();

}

}

允许多个线程同时访问 信号量Semaphore

可以允许n个线程同时访问,结合公平锁。

3.1.4 读写锁

ReadWriteLock JDK

/**

* @author ChengBing Han

* @date 14:44 2018/7/7

* @description

*/

public class ReadWriteLockDemo {

public static ReentrantLock lock = new ReentrantLock();

private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

public static Lock readLock = reentrantReadWriteLock.readLock();

public static Lock writeLock = reentrantReadWriteLock.writeLock();

public static int value;

private static int index = 0;

public static Object handleRead(Lock lock) {

lock.lock();

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

lock.unlock();

}

System.out.println("read value is " + value);

return value;

}

public static void handleWrite(Lock lock, int newValue) {

lock.lock();

try {

Thread.sleep(1000);

value = newValue;

System.out.println("write value is " + value);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

public static void main(String[] args) {

final long startTime = System.currentTimeMillis();

final Runnable readRunnable = new Runnable() {

public void run() {

handleRead(readLock);

}

};

final Runnable writeRunnable = new Runnable() {

public void run() {

handleWrite(writeLock, ++index);

}

};

for (int i = 0; i < 10; i++) {

final Thread thread = new Thread(readRunnable);

thread.start();

}

for (int i = 0; i < 10; i++) {

final Thread thread = new Thread(writeRunnable);

thread.start();

}

//为什么要在while中输出一些东西呢

//如果还是一个空的While循环,while 会被优化在-Server模式下

while (value != 10){

System.out.print("");

}

final long end = System.currentTimeMillis();

System.out.println("app use :" + (end - startTime)/1000);

}

}

倒计时(线程个数)器: CountDownLatch

可以让n线程都完成任务了,在继续执行某个主线程。例如,火箭发射前有10个检查任务,这时创建10个线程分别处理十个任务,再创建一个发射火箭的线程,每次完成一个检查任务,CountDownLatch 记录一个,这样,可以等10个都完成了,发射火箭的线程再执行。

倒计时器的扩展:循栅栏。

扩展了CountDownLatch,将军让10个士兵为1组, 这样一组的完成类似于CountDownLatch, 如果与多组就用循环栅栏。 可以循环多组。

线程阻塞工具类:LockSupport

提供一些阻塞的功能

3.2 线程复用:线程池

3.2.1什么是线程池

同数据库连接池

3.3.2不要重复造轮子:jdk对线程池的支持

Executors 是什么?

一言蔽之:工厂

Executors的介绍:

/**

* Factory and utility methods for {@link Executor}, {@link

* ExecutorService}, {@link ScheduledExecutorService}, {@link

* ThreadFactory}, and {@link Callable} classes defined in this

* package. This class supports the following kinds of methods:

*

*

*

Methods that create and return an {@link ExecutorService}

* set up with commonly useful configuration settings.

*

Methods that create and return a {@link ScheduledExecutorService}

* set up with commonly useful configuration settings.

*

Methods that create and return a "wrapped" ExecutorService, that

* disables reconfiguration by making implementation-specific methods

* inaccessible.

*

Methods that create and return a {@link ThreadFactory}

* that sets newly created threads to a known state.

*

Methods that create and return a {@link Callable}

* out of other closure-like forms, so they can be used

* in execution methods requiring {@code Callable}.

*

*

* @since 1.5

* @author Doug Lea

*/

线程池说明

固定数量的线程池

弊端:如果线程池中有5个任务,第一个任务

/**

* @author ChengBing Han

* @date 12:19 2018/7/14

* @description

*/

public class FixThreadPoolTest {

public static class MyTask implements Runnable{

public void run() {

final long id = Thread.currentThread().getId();

System.out.println("当前线程的id是: " + id);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

final ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);

for (int i = 0; i < 10; i++) {

newFixedThreadPool.submit(new MyTask());

}

}

}

通过输出可以看到,10个任务,用池子中的了5个线程

**output:**

当前线程的id是: 13

当前线程的id是: 15

当前线程的id是: 16

当前线程的id是: 13

当前线程的id是: 14

当前线程的id是: 17

当前线程的id是: 15

当前线程的id是: 16

当前线程的id是: 13

当前线程的id是: 14

异常处理

/**

* @author ChengBing Han

* @date 12:19 2018/7/14

* @description

*/

public class FixThreadPoolTest {

static boolean flag = true;

public static class MyTask implements Runnable{

public void run() {

if(flag){

flag=false;

System.out.println("出现异常");

System.out.println(1/0);

System.out.println("异常结束");

}

final long id = Thread.currentThread().getId();

System.out.println("当前线程的id是: " + id);

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

final ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);

for (int i = 0; i < 10; i++) {

newFixedThreadPool.submit(new MyTask());

}

newFixedThreadPool.shutdown();

}

}

output:

出现异常

当前线程的id是: 11

当前线程的id是: 14

当前线程的id是: 15

当前线程的id是: 13

当前线程的id是: 12

当前线程的id是: 14

当前线程的id是: 15

当前线程的id是: 11

当前线程的id是: 13

**结论:根据上述输出,可以发现,线程次中有10次调用,某次发生异常,不会影响其它的9次**

定时线程:

/**

* @author ChengBing Han

* @date 12:24 2018/7/14

* @description

*/

public class SheduleThreadPoolTest {

public static class MyTask implements Runnable{

public void run() {

System.out.println("Thread is run which id is : " + Thread.currentThread().getId());

}

}

public static void main(String[] args) {

final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);

scheduledExecutorService.scheduleAtFixedRate(new MyTask(),10,1,TimeUnit.SECONDS);

}

}

*注意定时的这个线程池和上述的newFixedThreadPool不同,一旦某个任务出现调度异常,那么后面的任务都不会再执行。==》做好异常处理工作。

*定时任务的两个方法不同之处在于

scheduleAtFixedRate: 每隔2秒调度一个任务,但是一个任务的时间是8秒(大于2秒)那么实际是8秒调度一个任务。

scheduleWithFixedDelay: 隔2秒调度一个任务,但是一个任务的时间是8秒(大于2秒)那么实际是8+2秒调度一个任务。

3.2.3 线程池的内部实现:

该部分待看书

java程序实现按并发数收费_java-实战java高并发程序设计-ch3JDK并发包相关推荐

  1. java 高并发第三阶段实战_Java 高并发第三阶段实战---Java并发包深入解析与使用详解...

    第三阶段的课程主要围绕着Java并发包的使用,展开详细的介绍,主要内容有1.原子包源码剖析,2.并发包工具类详细介绍,3.线程服务以及Future和callable等详细介绍,4.高并发容器和阻塞容器 ...

  2. java程序实现可移植性依靠的是_Java第2版-习题参考答案

    习题参考答案 --Java程序设计实用教程(第2版) 第1章绪论 1.1 (1)简单性--Java对系统软.硬件要求低:也比较容易学习. (2)面向对象--Java是纯面向对象的语言. (3)分布性- ...

  3. java程序的装载与检查_浅谈Java类型装载、连接与初始化

    类型装载.连接与初始化 Java虚拟机通过装载.连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用.其中装载就是把二进制形式的Java class文件读入Java虚拟机中去;连接 ...

  4. Java 高并发第三阶段实战---Java并发包深入解析与使用详解

    第三阶段的课程主要围绕着Java并发包的使用,展开详细的介绍,主要内容有1.原子包源码剖析,2.并发包工具类详细介绍,3.线程服务以及Future和callable等详细介绍,4.高并发容器和阻塞容器 ...

  5. 高并发第一弹:准备阶段 了解高并发

    高并发第一弹:准备阶段 了解高并发 首先需要知道什么并发, 什么是高并发. 并发: 关于并发的学习,可以从JDK提供的并发包为核心开始,许多其他的类和封装都是对其进行扩展或者补充,我们来看一下Java ...

  6. Spring Boot实战解决高并发数据入库: Redis 缓存+MySQL 批量入库

    前言 最近在做阅读类的业务,需要记录用户的PV,UV: 项目状况:前期尝试业务阶段: 特点: 快速实现(不需要做太重,满足初期推广运营即可) 快速投入市场去运营 收集用户的原始数据,三要素: 谁 在什 ...

  7. 高并发专题--5:关于redis高并发你晓得多少?

    关于redis高并发你晓得多少? 1.redis高并发跟整个系统的高并发之间的关系 2.redis不能支撑高并发的瓶颈在哪里? 3.如果redis要支撑超过10万+的并发,那应该怎么做? 4.redi ...

  8. java唯一订单号_java web在高并发和分布式下实现订单号生成唯一的解决方案

    方案一: 如果没有并发,订单号只在一个线程内产生,那么由于程序是顺序执行的,不同订单的生成时间戳正常不同,因此用时间戳+随机数(或自增数)就可以区分各个订单.如果存在并发,且订单号是由一个进程中的多个 ...

  9. java如何解决高并发问题_java怎么处理高并发?

    java处理高并发的方法:1.优化代码,减少不必要的资源浪费:2.把图片与页面进行分离,将图片放到独立的图片服器:3.使用缓存,可以大量减少与数据库的交互,提高性能:4.使用数据库集群:5.进行DB优 ...

最新文章

  1. Spring Boot 搭载属于你的网站框架(一)
  2. 25、Java Swing文本编辑器的实现
  3. C/Cpp / 设计模式 / 简单工厂模式
  4. 需求调研 现有系统梳理_对速度的需求,访问现有数据的速度提高了1000倍
  5. mysql内连接部门平均值_详解MySql基本查询、连接查询、子查询、正则表达查询_MySQL...
  6. python @符号_用Python学数学之Sympy代数符号运算
  7. 工业路由器和家用路由器有什么区别?
  8. HTML 表格滚动锁定表头,实现固定行列
  9. 企业如何搭建内部知识库Wiki?为什么需要知识库?
  10. 互融云工业品电商系统上线:科技助力互联网与实体经济深度融合
  11. uk码对照表_鞋码对照表_UK鞋码对照表
  12. 信息安全三级易错题总结
  13. Filezilla 连接不上 Error: Connection timed out after 20 seconds of inactivity
  14. Leetcode_35_Search Insert Position
  15. 成为一名合格的软件测试工程师,需要具备哪些技能?
  16. 东文财、赵栋《面向对象程序设计(java)》第十一周学习总结
  17. 【好星球】热门影视免费看,直链播放,可倍速
  18. AndroidManifest.xml解析
  19. 使用win10自带的手机投屏功能
  20. (项目)在线教育平台(十二)

热门文章

  1. Mysql笔记2-----重要小点
  2. 第六十二课、单例类模板
  3. 阿里云云服务器Centos7部署JDK8+Nginx+Tomcat8+Mysql5.7
  4. 1、orcal database 11g体系机构概述
  5. visualVM 安装使用
  6. 职场小窍门:看穿同事性格的16个小动作
  7. 您的主机不满足在启用hyper-v或device_是时候换掉你的旧书桌了!乐歌E5M电动升降桌,坐立换姿不疲劳...
  8. Python实现:详解LRU缓存淘汰算法
  9. 加来道雄 基因编辑 纳米机器人_浙大专家把螺旋藻制成微纳机器人,可通过光合作用靶向治疗肿瘤...
  10. 分布式 java 应用:基础与实践_西研技术大讲堂第二期FRCS应用情况介绍及分布式技术平台能力应用实践...