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. 从原则、方案、策略及难点阐述分库分表
  2. python中的有序字典
  3. 第一个以比特币现金ICO的项目,筹集了3000万美元
  4. 多元统计分析-判别分析
  5. gogs mysql 报错_linux上Docker安装gogs私服亲测(详解)
  6. 产品路线图的三种模型(RICE/MoSCoW/Kano),教你如何对需求进行优先级排序
  7. 【转】[C++]LARGE_INTEGER 类型使用
  8. MySQL百一题库_「灵魂拷问」MySQL面试高频一百问(工程师方向)
  9. 修改value_EXCEL批量名称修改
  10. mysql中用来取余数的函数是_MySQL常用函数-单行处理函数-字符串处理函数(更新中...)...
  11. git本地分支和远程分支操作
  12. 2017.10.17 蜘蛛难题 思考记录
  13. 实现机器学习的循序渐进指南VIII——线性回归
  14. asp.net应用程序级别跟踪
  15. 电脑全能工具箱,400+工具免费用
  16. 分享一个网盘:千脑网
  17. Redis开发与运维之第五章持久化
  18. 创新实训(6)——有关博客的摘要抽取的算法实现(TextRank)
  19. 如何配置一台深度学习的主机
  20. 关于VMware上的VAAI特性详解

热门文章

  1. CentOS SVN服务器管理多项目
  2. selenium 常用操作
  3. asp.net C# 实现微信接口权限开发类
  4. 《翻译》Intel 64 与 IA-32 架构软件开发者手册卷1翻译
  5. Response.getWriter() 和Response.getOutputStream冲突
  6. 推荐65个以自然风光为背景的UI设计
  7. 如何建立顺畅的项目流程
  8. 优词词根词典mdx_推荐|一波好用的在线英语词典网站
  9. matlab 打开txt文件窗口,Matlab读取txt文件、xlsx文件
  10. 非线性方程组牛顿迭代法matlab,matlab实现牛顿迭代法求解非线性方程组