├── .idea
├── .name
├── codeStyleSettings.xml
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── findbugs-idea.xml
├── misc.xml
├── modules.xml
├── scopes
│ └── scope_settings.xml
├── uiDesigner.xml
└── vcs.xml
├── 01-02-线程的创建和运行
├── 01-02-线程的创建和运行.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── Calculator.java
├── 01-03-线程信息的获取和设置
├── 01-03-线程信息的获取和设置.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── Calculator.java
├── 01-04-线程的中断
├── 01-04-线程的中断.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── PrimeGenerator.java
├── 01-05-线程中断的控制
├── 01-05-线程中断的控制.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── FileSearch.java
├── 01-06-线程的休眠和恢复
├── 01-06-线程的休眠和恢复.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── FileClock.java
├── 01-07-等待线程的终止
├── 01-07-等待线程的终止.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── DataSourcesLoader.java
│ └── NetworkConnectionsLoader.java
├── 01-08-守护线程的创建和运行
├── 01-08-守护线程的创建和运行.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── event
│ └── Event.java
│ └── task
│ ├── CleanerTask.java
│ └── WriterTask.java
├── 01-09-线程中不可控异常的处理
├── 01-09-线程中不可控异常的处理.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── handler
│ └── ExceptionHandler.java
│ └── task
│ └── Task.java
├── 01-10-线程局部变量的使用
├── 01-10-线程局部变量的使用.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ ├── Main.java
│ └── SafeMain.java
│ └── task
│ ├── SafeTask.java
│ └── UnsafeTask.java
├── 01-11-线程分组
├── 01-11-线程分组.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Result.java
│ └── SearchTask.java
├── 01-12-线程组中不可控制异常的处理
├── 01-12-线程组中不可控制异常的处理.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── group
│ └── MyThreadGroup.java
│ └── task
│ └── Task.java
├── 01-13-使用工厂类创建线程
├── 01-13-使用工厂类创建线程.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── factory
│ └── MyThreadFactory.java
│ └── task
│ └── Task.java
├── 02-02-使用synchronized实现同步方法-问题
├── 02-02-使用synchronized实现同步方法-问题.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Account.java
│ ├── Bank.java
│ └── Company.java
├── 02-02-使用synchronized实现同步方法-问题解决
├── 02-02-使用synchronized实现同步方法-问题解决.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Account.java
│ ├── Bank.java
│ └── Company.java
├── 02-03-使用非依赖属性实现同步
├── 02-03-使用非依赖属性实现同步.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Cinema.java
│ ├── TicketOffice1.java
│ └── TicketOffice2.java
├── 02-04-在同步代码中使用条件
├── 02-04-在同步代码中使用条件.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Consumer.java
│ ├── EventStorage.java
│ └── Producer.java
├── 02-05-用锁实现同步
├── 02-05-用锁实现同步.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Job.java
│ └── PrintQueue.java
├── 02-06-使用读写锁实现同步数据访问
├── 02-06-使用读写锁实现同步数据访问.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── PricesInfo.java
│ ├── Reader.java
│ └── Writer.java
├── 02-07-修改锁的公平性
├── 02-07-修改锁的公平性.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Job.java
│ └── PrintQueue.java
├── 02-08-在锁中使用多条件
├── 02-08-在锁中使用多条件.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── task
│ ├── Consumer.java
│ └── Producer.java
│ └── utils
│ ├── Buffer.java
│ └── FileMock.java
├── 02-09-应用例子
├── 02-09-应用例子.iml
└── src
│ └── com.concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── BuildStats.java
│ ├── Sensor1.java
│ └── Sensor2.java
├── 03-02-资源并发控制访问
├── 03-02-资源并发控制访问.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Job.java
│ └── PrintQueue.java
├── 03-03-资源的多副本的并发访问控制
├── 03-03-资源的多副本的并发访问控制.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Job.java
│ └── PrintQueue.java
├── 03-04-等待多个并发事件的完成
├── 03-04-等待多个并发事件的完成.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Participant.java
│ └── VideoConference.java
├── 03-05-在集合点的同步
├── 03-05-在集合点的同步.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── task
│ ├── Grouper.java
│ └── Searcher.java
│ └── utils
│ ├── MatrixMock.java
│ └── Results.java
├── 03-06-并发阶段任务的运行
├── 03-06-并发阶段任务的运行.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── FileSearch.java
├── 03-07-并发阶段任务中的阶段切换
├── 03-07-并发阶段任务中的阶段切换.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── MyPhaser.java
│ └── Student.java
├── 03-08-并发任务间的数据交换
├── 03-08-并发任务间的数据交换.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Consumer.java
│ └── Producer.java
├── 04-02-创建线程执行器
├── 04-02-创建线程执行器.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Server.java
│ └── Task.java
├── 04-03-创建固定大小的线程执行器
├── 04-03-创建固定大小的线程执行器.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Server.java
│ └── Task.java
├── 04-04-在执行器中执行任务并返回结果
├── 04-04-在执行器中执行任务并返回结果.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── FactorialCalculator.java
├── 04-05-运行多个任务并处理第一个结果
├── 04-05-运行多个任务并处理第一个结果.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── TaskValidator.java
│ └── UserValidator.java
├── 04-06-运行多个任务并且处理所有结果
├── 04-06-运行多个任务并且处理所有结果.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Result.java
│ └── Task.java
├── 04-07-在执行器中延时执行任务
├── 04-07-在执行器中延时执行任务.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── Task.java
├── 04-08-在执行器中周期性执行任务
├── 04-08-在执行器中周期性执行任务.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── Task.java
├── 04-09-在执行器中取消任务
├── 04-09-在执行器中取消任务.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── Task.java
├── 04-10-在执行器中控制任务的完成
├── 04-10-在执行器中控制任务的完成.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── ExecutableTask.java
│ └── ResultTask.java
├── 04-11-在执行器中分离任务的启动与结果的处理
├── 04-11-在执行器中分离任务的启动与结果的处理.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── ReportGenerator.java
│ ├── ReportProcessor.java
│ └── ReportRequest.java
├── 04-12-处理在执行器中被拒绝的任务
├── 04-12-处理在执行器中被拒绝的任务.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── RejectedTaskController.java
│ └── Task.java
├── 05-02-创建Fork-Join线程池
├── 05-02-创建Fork-Join线程池.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── task
│ └── Task.java
│ └── utils
│ ├── Product.java
│ └── ProductListGenerator.java
├── 05-03-合并任务的结果
├── 05-03-合并任务的结果.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── task
│ ├── DocumentTask.java
│ └── LineTask.java
│ └── utils
│ └── DocumentMock.java
├── 05-04-异步运行任务
├── 05-04-异步运行任务.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── FolderProcessor.java
├── 05-05-在任务中抛出异常
├── 05-05-在任务中抛出异常.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── Task.java
├── 05-06-取消任务
├── 05-06-取消任务.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── task
│ └── TaskManager.java
│ └── utils
│ ├── ArrayGenerator.java
│ └── SearchNumberTask.java
├── 06-02-使用非阻塞式线程安全列表
├── 06-02-使用非阻塞式线程安全列表.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── AddTask.java
│ └── PollTask.java
├── 06-03-使用阻塞式线程安全列表
├── 06-03-使用阻塞式线程安全列表.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── Client.java
├── 06-04-使用按优先级排序的阻塞式线程安全列表
├── 06-04-使用按优先级排序的阻塞式线程安全列表.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Event.java
│ └── Task.java
├── 06-05-使用带有延迟元素的线程安全列表
├── 06-05-使用带有延迟元素的线程安全列表.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Event.java
│ └── Task.java
├── 06-06-使用线程安全可遍历映射
├── 06-06-使用线程安全可遍历映射.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── task
│ └── Task.java
│ └── utils
│ └── Contact.java
├── 06-07-生成并发随机数
├── 06-07-生成并发随机数.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── TaskLocalRandom.java
├── 06-08-使用原子变量
├── 06-08-使用原子变量.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Account.java
│ ├── Bank.java
│ └── Company.java
├── 06-09-使用原子数组
├── 06-09-使用原子数组.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Decrementer.java
│ └── Incrementer.java
├── 07-02-定制ThreadPoolExecutor类
├── 07-02-定制ThreadPoolExecutor类.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ ├── executor
│ └── MyExecutor.java
│ └── task
│ └── SleepTwoSecondsTask.java
├── 07-03-基于优先级的Executor类
├── 07-03-基于优先级的Executor类.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ └── MyPriorityTask.java
├── 07-04-实现ThreadFactory接口生成定制线程
├── 07-04-实现ThreadFactory接口生成定制线程.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── MyTask.java
│ ├── MyThread.java
│ └── MyThreadFactory.java
├── 07-05-在Executro对象中使用ThreadFactory
├── 07-05-在Executro对象中使用ThreadFactory.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── MyTask.java
│ ├── MyThread.java
│ └── MyThreadFactory.java
├── 07-06-定制运行在线程池中的任务
├── 07-06-定制运行在线程池中的任务.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── MyScheduledTask.java
│ ├── MyScheduledThreadPoolExecutor.java
│ └── Task.java
├── 07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程
├── 07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── MyRecursiveTask.java
│ ├── MyWorkerThread.java
│ └── MyWorkerThreadFactory.java
├── 07-08-定制运行在Fork-Join框架中的任务
├── 07-08-定制运行在Fork-Join框架中的任务.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── MyWorkerTask.java
│ └── Task.java
├── 07-09-现实定制Lock类
├── 07-09-现实定制Lock类.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── MyAbstractQueuedSynchronizer.java
│ ├── MyLock.java
│ └── Task.java
├── 07-10-实现基于优先级的传输队列
├── 07-10-实现基于优先级的传输队列.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── Consumer.java
│ ├── Event.java
│ ├── MyPriorityTransferQueue.java
│ └── Producer.java
├── 07-11-实现自己的原子对象
├── 07-11-实现自己的原子对象.iml
└── src
│ └── com
│ └── concurrency
│ ├── core
│ └── Main.java
│ └── task
│ ├── ParkingCounter.java
│ ├── Sensor1.java
│ └── Sensor2.java
├── README.md
└── Template
└── Template.iml
/.idea/.name:
--------------------------------------------------------------------------------
1 | JAVA7并发编程实战手册
--------------------------------------------------------------------------------
/.idea/codeStyleSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/01-02-线程的创建和运行/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Calculator;
4 |
5 | public class Main {
6 | public static void main(String[] args) {
7 | // 创建一个执行10次的循环。在每次循环中创建一个Calculator 对象,
8 | // 一个Thread对象,这个Thread对象使用刚创建的Calculator对象作为构造器的参数,
9 | // 然后调用刚创建的Thread对象的start()方法。
10 | for (int i = 0; i <= 10; i++) {
11 | Calculator calculator = new Calculator(i);
12 | Thread thread = new Thread(calculator);
13 | thread.start();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/01-02-线程的创建和运行/src/com/concurrency/task/Calculator.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | // 创建一个名为Calculator的类,它实现了 Runnable接口
4 | public class Calculator implements Runnable {
5 | // 声明一个名为number的私有(private) int属性
6 | private int number;
7 |
8 | // 编写这个类的一个构造器,用来为属性number设置值。
9 | public Calculator(int number) {
10 | this.number = number;
11 | }
12 |
13 | // run方法。这个方法用来执行我们创建的线程的指令,它将对指定的数字进行乘法表运算。
14 | @Override
15 | public void run() {
16 | for (int i = 1; i <= 10; i++) {
17 | System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(), number, i, number * i);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/01-03-线程信息的获取和设置/src/com/concurrency/task/Calculator.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | public class Calculator implements Runnable{
4 | private int number;
5 |
6 | public Calculator(int number) {
7 | this.number = number;
8 | }
9 |
10 | @Override
11 | public void run() {
12 | // 指定的数字进行乘法表运算。
13 | for (int i = 1; i <= 10; i++) {
14 | System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(), number, i, number * i);
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/01-04-线程的中断/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.PrimeGenerator;
4 |
5 | import java.util.concurrent.TimeUnit;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 |
10 | Thread task = new PrimeGenerator();
11 | task.start(); // 启动质数生成线程
12 | try {
13 | TimeUnit.SECONDS.sleep(5); // 主线程休眠5s
14 | } catch (InterruptedException e) {
15 | e.printStackTrace();
16 | }
17 |
18 | task.interrupt(); // 质数生成线程中断
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/01-04-线程的中断/src/com/concurrency/task/PrimeGenerator.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | public class PrimeGenerator extends Thread {
4 | @Override
5 | public void run() {
6 | long number = 1L;
7 |
8 | while (true) {
9 | // 对每个数字,计算它是不是一个质数,如果是的话就打印到控制台。
10 | if (isPrime(number)) {
11 | System.out.printf("Number %d is Prime\n", number);
12 | }
13 |
14 | // 当被中断时,输出一条消息,并且退出方法
15 | if (isInterrupted()) {
16 | System.out.printf("The Prime Generator has been Interrupted\n");
17 | return;
18 | }
19 | number++;
20 | }
21 | }
22 |
23 | /**
24 | * 判断一个数是否是质数
25 | *
26 | * @param number 待判断的数
27 | * @return true是质数,false不是质数
28 | */
29 | private boolean isPrime(long number) {
30 | if (number <= 2) {
31 | return true;
32 | }
33 |
34 | for (long i = 2; i < number; i++) {
35 | if (number % i == 0) {
36 | return false;
37 | }
38 | }
39 | return true;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/01-05-线程中断的控制/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.FileSearch;
4 |
5 | import java.util.concurrent.TimeUnit;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建一个运行对象和一个运行它的线程
10 | FileSearch searcher = new FileSearch("C:/", "readme.txt");
11 | Thread thread = new Thread(searcher);
12 |
13 | thread.start(); // 启动线程
14 |
15 | try {
16 | TimeUnit.SECONDS.sleep(10); // 主线程休眠10s
17 | } catch (InterruptedException e) {
18 | e.printStackTrace();
19 | }
20 |
21 | thread.interrupt(); // 中断线程
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/01-05-线程中断的控制/src/com/concurrency/task/FileSearch.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.io.File;
4 |
5 | // 文件搜索类,给定一个文件目录,搜索其中指定的文件
6 | public class FileSearch implements Runnable {
7 | /**
8 | * 搜索的初始路径
9 | */
10 | private String initPath;
11 | /**
12 | * 要搜索的文件名
13 | */
14 | private String fileName;
15 |
16 |
17 | /**
18 | * 构造函数
19 | *
20 | * @param initPath 搜索的初始路径
21 | * @param fileName 要搜索的文件名
22 | */
23 | public FileSearch(String initPath, String fileName) {
24 | this.initPath = initPath;
25 | this.fileName = fileName;
26 | }
27 |
28 | @Override
29 | public void run() {
30 |
31 | }
32 |
33 | /**
34 | * 清空资源,在本例中为空
35 | */
36 | private void cleanResources() {
37 | // 不需要做什么
38 | }
39 |
40 | /**
41 | * 处理目录
42 | *
43 | * @param file 待处理的目录
44 | * @throws InterruptedException 线程被中断时抛出异常
45 | */
46 | private void directoryProcess(File file) throws InterruptedException {
47 | File[] list = file.listFiles(); // 获取当目录中的所有文件
48 | if (list != null) { // 如果当前目录下有文件
49 | for (int i = 0; i < list.length; i++) { // 遍布所有文件
50 | if (list[i].isDirectory()) { // 如果是一个目录
51 | directoryProcess(list[i]); // 递归处理
52 | } else {
53 | fileProcess(list[i]); // 如果是一个文件,调用文件处理方法
54 | }
55 | }
56 | }
57 | }
58 |
59 | /**
60 | * 文件处理方法
61 | *
62 | * @param file 待处理的文件名
63 | * @throws InterruptedException 线程被中断时抛出异常
64 | */
65 | private void fileProcess(File file) throws InterruptedException {
66 | if (file.getName().equals(this.fileName)) { // 当前文件名与要查找的文件同名,就输出信息
67 | System.out.printf("%s : %s\n", Thread.currentThread().getName(), file.getAbsolutePath());
68 | }
69 |
70 | if (Thread.interrupted()) { // 程序被中断就抛出异常
71 | throw new InterruptedException();
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/01-06-线程的休眠和恢复/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.FileClock;
4 |
5 | import java.util.concurrent.TimeUnit;
6 | public class Main {
7 | public static void main(String[] args) {
8 | // 创建一个文件时间运行对象,并且将其放入一个线程对象中
9 | FileClock clock = new FileClock();
10 | Thread thread = new Thread(clock);
11 |
12 | // 开始线程
13 | thread.start();
14 | try {
15 | // 等待五秒
16 | TimeUnit.SECONDS.sleep(5);
17 | } catch (InterruptedException e) {
18 | e.printStackTrace();
19 | }
20 |
21 | // 中断线程
22 | thread.interrupt();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/01-06-线程的休眠和恢复/src/com/concurrency/task/FileClock.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | // 文件定时类,每隔一秒钟将实际的时间输出
7 | public class FileClock implements Runnable {
8 | @Override
9 | public void run() {
10 | for (int i = 0; i < 10; i++) {
11 | System.out.printf("%s\n", new Date());
12 | try {
13 | // 休眠一秒
14 | TimeUnit.SECONDS.sleep(1);
15 | } catch (InterruptedException e) {
16 | // 当线程被中断时,释放或者关闭线程正在使用的资源。
17 | System.out.printf("The FileClock has been interrupted");
18 | return; // 发生异常就跳出
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/01-07-等待线程的终止/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.DataSourcesLoader;
4 | import com.concurrency.task.NetworkConnectionsLoader;
5 |
6 | import java.util.Date;
7 |
8 | public class Main {
9 | public static void main(String[] args) {
10 | // 创建并启动数据源加载器
11 | DataSourcesLoader dsLoader = new DataSourcesLoader();
12 | Thread thread1 = new Thread(dsLoader, "DataSourceThread");
13 | thread1.start();
14 |
15 | // 创建并且启动网络连接加载器
16 | NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
17 | Thread thread2 = new Thread(ncLoader, "NetworkConnectionLoader");
18 | thread2.start();
19 |
20 | // 待待两个线程的任务完成
21 | try {
22 | thread1.join();
23 | thread2.join();
24 | } catch (InterruptedException e) {
25 | e.printStackTrace();
26 | }
27 |
28 | // 两个任务都完成后输出一条消息
29 | System.out.printf("Main: Configuration has been loaded: %s\n", new Date());
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/01-07-等待线程的终止/src/com/concurrency/task/DataSourcesLoader.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 数据源加载器,模拟数据加载,它会休眠10s
8 | */
9 | public class DataSourcesLoader implements Runnable {
10 | @Override
11 | public void run() {
12 | // 输出一条消息
13 | System.out.printf("Beginning data sources loading: %s\n",new Date());
14 |
15 | // 休眠10s
16 | try {
17 | TimeUnit.SECONDS.sleep(4);
18 | } catch (InterruptedException e) {
19 | e.printStackTrace();
20 | }
21 | // 输出一条消息
22 | System.out.printf("Data sources loading has finished: %s\n",new Date());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/01-07-等待线程的终止/src/com/concurrency/task/NetworkConnectionsLoader.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 网络连接加载器,模拟网络连接,它会休眠6s
8 | */
9 | public class NetworkConnectionsLoader implements Runnable {
10 | @Override
11 | public void run() {
12 | // 输出一条消息
13 | System.out.printf("Begining network connections loading: %s\n",new Date());
14 |
15 | // 休眠6s
16 | try {
17 | TimeUnit.SECONDS.sleep(6);
18 | } catch (InterruptedException e) {
19 | e.printStackTrace();
20 | }
21 | // 输出一条消息
22 | System.out.printf("Network connections loading has finished: %s\n",new Date());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/01-08-守护线程的创建和运行/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.event.Event;
4 | import com.concurrency.task.CleanerTask;
5 | import com.concurrency.task.WriterTask;
6 |
7 | import java.util.ArrayDeque;
8 | import java.util.Deque;
9 |
10 | public class Main {
11 | public static void main(String[] args) {
12 | // 创建一个用于存放事件对象的队列
13 | Deque deque = new ArrayDeque();
14 |
15 | // 创建一个写任务的对象,并且创建三个线程去调用这个对象
16 | WriterTask writer = new WriterTask(deque);
17 | for (int i = 0; i < 3; i++) {
18 | Thread thread = new Thread(writer);
19 | thread.start();
20 | }
21 |
22 | // 创建一个事件清除任务,并且启动这个任务
23 | CleanerTask cleaner = new CleanerTask(deque);
24 | cleaner.start();
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/01-08-守护线程的创建和运行/src/com/concurrency/event/Event.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.event;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * 事件类,存储事件信息
7 | */
8 | public class Event {
9 | /**
10 | * 事件日期
11 | */
12 | private Date date;
13 | /**
14 | * 事件信息
15 | */
16 | private String event;
17 |
18 | /**
19 | * 获取事件日期
20 | *
21 | * @return 事件日期
22 | */
23 | public Date getDate() {
24 | return date;
25 | }
26 |
27 | /**
28 | * 设置事件日期
29 | *
30 | * @param date 事件日期
31 | */
32 | public void setDate(Date date) {
33 | this.date = date;
34 | }
35 |
36 | /**
37 | * 获取事件信息
38 | *
39 | * @return 事件信息
40 | */
41 | public String getEvent() {
42 | return event;
43 | }
44 |
45 | /**
46 | * 设置事件信息
47 | *
48 | * @param event 事件信息
49 | */
50 | public void setEvent(String event) {
51 | this.event = event;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/01-08-守护线程的创建和运行/src/com/concurrency/task/CleanerTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.event.Event;
4 |
5 | import java.util.Date;
6 | import java.util.Deque;
7 |
8 | /**
9 | * 事件清除类,每隔10秒从队尾取出一个事件,并且删除这个事件
10 | */
11 | public class CleanerTask extends Thread {
12 |
13 | /**
14 | * 用于存储事件对象的队列
15 | */
16 | Deque deque;
17 |
18 | /**
19 | * 构造函数
20 | *
21 | * @param deque 存储事件对象的队列
22 | */
23 | public CleanerTask(Deque deque) {
24 | this.deque = deque;
25 | setDaemon(true); // 表明当前对象是一个精灵线程
26 | }
27 |
28 |
29 | @Override
30 | public void run() {
31 | while (true) {
32 | Date date = new Date();
33 | clean(date);
34 | }
35 | }
36 |
37 | /**
38 | * 清除方法,生存时间长于10秒的事件进行清除
39 | * @param date 当前时间
40 | */
41 | private void clean(Date date) {
42 | long difference;
43 | boolean delete;
44 |
45 | if (this.deque.size() == 0) {
46 | return;
47 | }
48 |
49 | delete = false;
50 | do {
51 | Event e = this.deque.getLast();
52 | difference = date.getTime() - e.getDate().getTime(); // 计算最早的事件距离现在的时间
53 | if (difference > 10000) { // 大于10秒就输出信息,并且删除最先发生的事件
54 | System.out.printf("Cleaner: %s\n", e.getEvent());
55 | deque.removeLast();
56 | delete = true;
57 | }
58 | } while (difference > 10000);
59 |
60 | if (delete) { // 有删除就输出删除后队列的大小
61 | System.out.printf("Cleaner: Size of the queue: %d\n", deque.size());
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/01-08-守护线程的创建和运行/src/com/concurrency/task/WriterTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.event.Event;
4 |
5 | import java.util.Date;
6 | import java.util.Deque;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | /**
10 | * 写事件的类,每一秒钟产生一个事件对象
11 | */
12 | public class WriterTask implements Runnable {
13 | /**
14 | * 用于存储事件对象的队列
15 | */
16 | Deque deque;
17 |
18 | /**
19 | * 构造函数
20 | *
21 | * @param deque 存储事件对象的队列
22 | */
23 | public WriterTask(Deque deque) {
24 | this.deque = deque;
25 | }
26 |
27 | @Override
28 | public void run() {
29 | // 产生100个事件对象
30 | for (int i = 1; i < 100; i++) {
31 | // 创建和初始化事件对象
32 | Event event = new Event();
33 | event.setDate(new Date());
34 | event.setEvent(String.format("The thread %s has generated an event", Thread.currentThread().getId()));
35 |
36 | // 将事件添加对队列头部
37 | deque.addFirst(event);
38 | try {
39 | // 休眠一秒种
40 | TimeUnit.SECONDS.sleep(1);
41 | } catch (InterruptedException e) {
42 | e.printStackTrace();
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/01-09-线程中不可控异常的处理/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.handler.ExceptionHandler;
4 | import com.concurrency.task.Task;
5 |
6 | public class Main {
7 | public static void main(String[] args) {
8 | Task task = new Task(); // 创建一个任务
9 | Thread thread = new Thread(task); // 创建一个线程
10 | thread.setUncaughtExceptionHandler(new ExceptionHandler()); // 设置线程的异常处理器
11 | thread.start();
12 |
13 | try {
14 | thread.join(); // 等待线程完成
15 | } catch (InterruptedException e) {
16 | e.printStackTrace();
17 | }
18 |
19 | System.out.printf("Thread has finished\n");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/01-09-线程中不可控异常的处理/src/com/concurrency/handler/ExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.handler;
2 |
3 | /**
4 | * 异常处理类,处理线程中抛出的未捕获的异常
5 | */
6 | public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
7 | /**
8 | * 处理线程中抛出的未捕获的异常
9 | * @param t 招聘异常的线程
10 | * @param e 抛出的异常
11 | */
12 | @Override
13 | public void uncaughtException(Thread t, Throwable e) {
14 | System.out.printf("An exception has been captured\n");
15 | System.out.printf("Thread: %s\n", t.getId());
16 | System.out.printf("Exception: %s: %s\n", e.getClass().getName(), e.getMessage());
17 | System.out.printf("Stack Trace: \n");
18 | e.printStackTrace(System.out);
19 | System.out.printf("Thread status: %s\n", t.getState());
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/01-09-线程中不可控异常的处理/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 任务类,专门抛出异常
5 | */
6 | public class Task implements Runnable {
7 | @Override
8 | public void run() {
9 | // 下面的语句会招聘异常
10 | int number = Integer.parseInt("TTT");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/01-10-线程局部变量的使用/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.UnsafeTask;
4 |
5 | import java.util.concurrent.TimeUnit;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建线程不安全的任务
10 | UnsafeTask task = new UnsafeTask();
11 |
12 | // 将任务入进三个不同的线程中
13 | for (int i = 0; i < 3; i++) {
14 | Thread thread = new Thread(task);
15 | thread.start();
16 | try {
17 | TimeUnit.SECONDS.sleep(2);
18 | } catch (InterruptedException e) {
19 | e.printStackTrace();
20 | }
21 | }
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/01-10-线程局部变量的使用/src/com/concurrency/core/SafeMain.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.SafeTask;
4 |
5 | import java.util.concurrent.TimeUnit;
6 |
7 | public class SafeMain {
8 | public static void main(String[] args) {
9 | // 创建一个任务
10 | SafeTask task = new SafeTask();
11 |
12 | // 将任务放入三个不同的线程中运行
13 | for (int i = 0; i < 3; i++) {
14 | Thread thread = new Thread(task);
15 | try {
16 | TimeUnit.SECONDS.sleep(2);
17 | } catch (InterruptedException e) {
18 | e.printStackTrace();
19 | }
20 | thread.start();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/01-10-线程局部变量的使用/src/com/concurrency/task/SafeTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | public class SafeTask implements Runnable {
7 | /**
8 | * 线程局部变量,其中的内容不能共享,线程被初始化时会创建其包含的变量
9 | */
10 | private static ThreadLocal startDate = new ThreadLocal() {
11 | @Override
12 | protected Date initialValue() {
13 | return new Date();
14 | }
15 | };
16 |
17 | @Override
18 | public void run() {
19 | System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread().getId(), startDate.get());
20 | try {
21 | TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10));
22 | } catch (InterruptedException e) {
23 | e.printStackTrace();
24 | }
25 |
26 | System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread().getId(), startDate.get());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/01-10-线程局部变量的使用/src/com/concurrency/task/UnsafeTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.sql.Time;
4 | import java.util.Date;
5 | import java.util.concurrent.TimeUnit;
6 |
7 | /**
8 | * 线程不安全的任务,当这个任务在多个线程中时,其中的变量会被多个线程其享
9 | */
10 | public class UnsafeTask implements Runnable {
11 | /**
12 | * 日期对象,被所有线程共享
13 | */
14 | private Date startDate;
15 |
16 | @Override
17 | public void run() {
18 | this.startDate = new Date();
19 | System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread().getId(), startDate);
20 | try {
21 | TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10));
22 | } catch (InterruptedException e) {
23 | e.printStackTrace();
24 | }
25 |
26 | System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread().getId(), startDate);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/01-11-线程分组/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Result;
4 | import com.concurrency.task.SearchTask;
5 |
6 | import java.util.concurrent.TimeUnit;
7 |
8 | public class Main {
9 | public static void main(String[] args) {
10 |
11 | // 创建一个线程组
12 | ThreadGroup threadGroup = new ThreadGroup("Searcher");
13 | // 创建一个结果对象
14 | Result result = new Result();
15 |
16 | // 创建一个搜索任务,并且创建5个线程去运行这个任务
17 | SearchTask searchTask = new SearchTask(result);
18 | for (int i = 0; i < 5; i++) {
19 | Thread thread = new Thread(threadGroup, searchTask);
20 | thread.start();
21 | try {
22 | TimeUnit.SECONDS.sleep(1);
23 | } catch (InterruptedException e) {
24 | e.printStackTrace();
25 | }
26 |
27 | }
28 |
29 | // 输出线程组的信息
30 | System.out.printf("Number of Threads: %d\n", threadGroup.activeCount());
31 | System.out.printf("Information about the Thread Group\n");
32 | threadGroup.list(); // 将有关此线程组的信息打印到标准输出。
33 |
34 | Thread[] threads = new Thread[threadGroup.activeCount()]; // 返回此线程组中活动线程的估计数。
35 | threadGroup.enumerate(threads); // 把此线程组及其子组中的所有活动线程复制到指定数组中。
36 | for (int i = 0; i < threadGroup.activeCount(); i++) {
37 | System.out.printf("Thread %s: %s\n", threads[i].getName(), threads[i].getState());
38 | }
39 |
40 | // 等待线程结束
41 | waitFinish(threadGroup);
42 |
43 | // 中断线程组中的所有线程
44 | threadGroup.interrupt();
45 |
46 | }
47 |
48 | /**
49 | * 等待线程组中的一个线程结束
50 | *
51 | * @param threadGroup 线程组
52 | */
53 | private static void waitFinish(ThreadGroup threadGroup) {
54 | while (threadGroup.activeCount() > 9) { // 如果线程组中的活动线程数大于9个,当前调用线程就休眠1秒,直到线程数小于9个
55 | try {
56 | TimeUnit.SECONDS.sleep(1);
57 | } catch (InterruptedException e) {
58 | e.printStackTrace();
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/01-11-线程分组/src/com/concurrency/task/Result.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 结果类用于存储搜索结果
5 | */
6 | public class Result {
7 | /**
8 | * 完成任务的线程名
9 | */
10 | private String name;
11 |
12 | /**
13 | * 获取完成任务的线程名
14 | * @return 完成任务的线程名
15 | */
16 | public String getName() {
17 | return name;
18 | }
19 |
20 | /**
21 | * 设置完成任务的线程名
22 | * @param name 完成任务的线程名
23 | */
24 | public void setName(String name) {
25 | this.name = name;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/01-11-线程分组/src/com/concurrency/task/SearchTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.Random;
5 | import java.util.concurrent.TimeUnit;
6 |
7 | public class SearchTask implements Runnable {
8 |
9 | /**
10 | * 如果线程完成了任务,并且没有中断,就存储线程的名字。
11 | */
12 | private Result result;
13 |
14 | /**
15 | * 构造函数
16 | *
17 | * @param result 结果对象
18 | */
19 | public SearchTask(Result result) {
20 | this.result = result;
21 | }
22 |
23 | @Override
24 | public void run() {
25 | String name = Thread.currentThread().getName();
26 | System.out.printf("Thread %s: Start\n", name);
27 | try {
28 | doTask();
29 | result.setName(name);
30 | } catch (InterruptedException e) {
31 | System.out.printf("Thread %s: Interrupted\n", name);
32 | return;
33 | }
34 | System.out.printf("Thread %s: End\n", name);
35 | }
36 |
37 | /**
38 | * 模拟搜索操作
39 | *
40 | * @throws InterruptedException 中断异常
41 | */
42 | private void doTask() throws InterruptedException {
43 | Random random = new Random((new Date()).getTime());
44 | int value = (int) (random.nextDouble() * 100);
45 | System.out.printf("Thread %s: %d\n", Thread.currentThread().getName(), value);
46 | TimeUnit.SECONDS.sleep(value);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/01-12-线程组中不可控制异常的处理/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.group.MyThreadGroup;
4 | import com.concurrency.task.Task;
5 |
6 | public class Main {
7 |
8 | public static void main(String[] args) {
9 | // 创建一个自定义的线程组
10 | MyThreadGroup threadGroup = new MyThreadGroup("MyThreadGroup");
11 | // 创建一个任务
12 | Task task = new Task();
13 | // 创建两个线程,将其放入同一个线程组中,并且执行同一个任务
14 | for (int i = 0; i < 2; i++) {
15 | Thread t = new Thread(threadGroup, task);
16 | t.start();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/01-12-线程组中不可控制异常的处理/src/com/concurrency/group/MyThreadGroup.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.group;
2 |
3 | public class MyThreadGroup extends ThreadGroup {
4 | /**
5 | * 构造函数
6 | *
7 | * @param name 线程组名称
8 | */
9 | public MyThreadGroup(String name) {
10 | super(name);
11 | }
12 |
13 | /**
14 | * 重写未捕获的异常方法
15 | *
16 | * @param t 抛出异常的信息
17 | * @param e 抛出的异常
18 | */
19 | @Override
20 | public void uncaughtException(Thread t, Throwable e) {
21 | // 打印线程的名称
22 | System.out.printf("The thread %s has thrown an Exception\n", t.getId());
23 | // 输出异常栈信息
24 | e.printStackTrace(System.out);
25 | // 中断线程组中其余的线程
26 | System.out.printf("Terminating the rest of the Threads\n");
27 | interrupt();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/01-12-线程组中不可控制异常的处理/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Random;
4 |
5 | public class Task implements Runnable {
6 | @Override
7 | public void run() {
8 | int result;
9 | // 创建一个随机数生成器
10 | Random random = new Random(Thread.currentThread().getId());
11 | while (true) {
12 | // 生成一个[0, 1000)内有随机整数,并且有1000除以这个数,求得商
13 | result = 1000 / ((int) (random.nextDouble() * 1000));
14 | System.out.printf("%s : %d\n", Thread.currentThread().getId(), result);
15 | // 检测当前线程是否被中断
16 | if (Thread.currentThread().isInterrupted()) {
17 | System.out.printf("%d : Interrupted\n", Thread.currentThread().getId());
18 | return;
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/01-13-使用工厂类创建线程/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.factory.MyThreadFactory;
4 | import com.concurrency.task.Task;
5 |
6 | public class Main {
7 | public static void main(String[] args) {
8 | // 创建一个线程工厂
9 | MyThreadFactory factory = new MyThreadFactory("MyThreadFactory");
10 | // 创建一个任务
11 | Task task = new Task();
12 | Thread thread;
13 |
14 | // 创建并且启动10个线程对象
15 | System.out.printf("Starting the Threads\n");
16 | for (int i = 0; i < 10; i++) {
17 | thread = factory.newThread(task);
18 | thread.start();
19 | }
20 | // 打印线程工厂的统计信息
21 | System.out.printf("Factory stats:\n");
22 | System.out.printf("%s\n", factory.getStats());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/01-13-使用工厂类创建线程/src/com/concurrency/factory/MyThreadFactory.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.factory;
2 |
3 | import com.sun.javafx.beans.annotations.NonNull;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Date;
7 | import java.util.Iterator;
8 | import java.util.List;
9 | import java.util.concurrent.ThreadFactory;
10 |
11 |
12 | public class MyThreadFactory implements ThreadFactory {
13 |
14 | private int counter; // 线程计数器,计数已经产生了多少个线程
15 | private String name; // 线程的基准名称
16 | private List stats; // 线程统计信息集合
17 |
18 | /**
19 | * 构造函数
20 | *
21 | * @param name 线程对象的基准名称
22 | */
23 | public MyThreadFactory(String name) {
24 | this.name = name;
25 | this.counter = 0;
26 | this.stats = new ArrayList();
27 | }
28 |
29 | /**
30 | * 使用Runnable对象创建一个线程
31 | *
32 | * @param r Runnable对象
33 | * @return 线程对象
34 | */
35 | @Override
36 | public Thread newThread(Runnable r) {
37 | // 创建一个新的线程对象
38 | Thread t = new Thread(r, this.name + "-Thread_" + this.counter);
39 | this.counter++;
40 | // Actualize the statistics of the factory
41 | this.stats.add(String.format("Created thread %d with name %s on %s\n", t.getId(), t.getName(), new Date()));
42 | return t;
43 | }
44 |
45 | /**
46 | * 获取线程工厂的统计信息
47 | *
48 | * @return 线程工厂的统计信息
49 | */
50 | public String getStats() {
51 | StringBuffer buffer = new StringBuffer();
52 | Iterator it = stats.iterator();
53 |
54 | while (it.hasNext()) {
55 | buffer.append(it.next());
56 | }
57 |
58 | return buffer.toString();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/01-13-使用工厂类创建线程/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | public class Task implements Runnable {
6 | @Override
7 | public void run() {
8 | try {
9 | TimeUnit.SECONDS.sleep(1);
10 | } catch (InterruptedException e) {
11 | e.printStackTrace();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/02-02-使用synchronized实现同步方法-问题/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Account;
4 | import com.concurrency.task.Bank;
5 | import com.concurrency.task.Company;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建一个帐户对象
10 | Account account = new Account();
11 | // 帐户初始值为1000
12 | account.setBalance(1000);
13 |
14 | // 创建一个公司对象,并且让公司对象在一个线程中运行
15 | Company company = new Company(account);
16 | Thread companyThread = new Thread(company);
17 |
18 | // 创建一个银行对象,并且让银行对象在一个线程中运行
19 | Bank bank = new Bank(account);
20 | Thread bankThread = new Thread(bank);
21 |
22 | // 输出初始的余额
23 | System.out.printf("Account : Initial Balance: %f\n", account.getBalance());
24 |
25 | // 启动公司和银行两个线程
26 | companyThread.start();
27 | bankThread.start();
28 |
29 | try {
30 | // 等待两个线程的完成
31 | companyThread.join();
32 | bankThread.join();
33 | // 输出最后的余额
34 | System.out.printf("Account : Final Balance: %f\n", account.getBalance());
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/02-02-使用synchronized实现同步方法-问题/src/com/concurrency/task/Account.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 帐户类,模拟一个银行帐户
5 | */
6 | public class Account {
7 | /**
8 | * 帐户余额
9 | */
10 | private double balance;
11 |
12 | /**
13 | * 获取帐户余额
14 | *
15 | * @return 帐户余额
16 | */
17 | public double getBalance() {
18 | return balance;
19 | }
20 |
21 | /**
22 | * 设置帐户余额
23 | *
24 | * @param balance 帐户余额
25 | */
26 | public void setBalance(double balance) {
27 | this.balance = balance;
28 | }
29 |
30 | /**
31 | * 增加帐户余额
32 | *
33 | * @param amount 增加的余额
34 | */
35 | public void addAccount(double amount) {
36 | double tmp = balance;
37 | try {
38 | Thread.sleep(10);
39 | } catch (InterruptedException e) {
40 | e.printStackTrace();
41 | }
42 |
43 | tmp += amount;
44 | balance = tmp;
45 | }
46 |
47 | /**
48 | * 减少帐户余额
49 | *
50 | * @param amount 减少的余额
51 | */
52 | public void subtractAmount(double amount) {
53 | double tmp = balance;
54 | try {
55 | Thread.sleep(10);
56 | } catch (InterruptedException e) {
57 | e.printStackTrace();
58 | }
59 |
60 | tmp -= amount;
61 | balance = tmp;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/02-02-使用synchronized实现同步方法-问题/src/com/concurrency/task/Bank.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | public class Bank implements Runnable {
4 | /**
5 | * 一个帐户
6 | */
7 | private Account account;
8 |
9 | /**
10 | * 构造函数
11 | *
12 | * @param account 银行帐户
13 | */
14 | public Bank(Account account) {
15 | this.account = account;
16 | }
17 |
18 |
19 | @Override
20 | public void run() {
21 | for (int i = 0; i < 100; i++) {
22 | this.account.subtractAmount(1000);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/02-02-使用synchronized实现同步方法-问题/src/com/concurrency/task/Company.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | public class Company implements Runnable {
4 |
5 | /**
6 | * 一个帐户
7 | */
8 | private Account account;
9 |
10 | /**
11 | * 构造函数
12 | * @param account 帐户对象
13 | */
14 | public Company(Account account) {
15 | this.account = account;
16 | }
17 |
18 | @Override
19 | public void run() {
20 | for (int i = 0; i < 100; i++) {
21 | this.account.addAccount(1000);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Account;
4 | import com.concurrency.task.Bank;
5 | import com.concurrency.task.Company;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建一个帐户对象
10 | Account account = new Account();
11 | // 帐户初始值为1000
12 | account.setBalance(1000);
13 |
14 | // 创建一个公司对象,并且让公司对象在一个线程中运行
15 | Company company = new Company(account);
16 | Thread companyThread = new Thread(company);
17 |
18 | // 创建一个银行对象,并且让银行对象在一个线程中运行
19 | Bank bank = new Bank(account);
20 | Thread bankThread = new Thread(bank);
21 |
22 | // 输出初始的余额
23 | System.out.printf("Account : Initial Balance: %f\n", account.getBalance());
24 |
25 | // 启动公司和银行两个线程
26 | companyThread.start();
27 | bankThread.start();
28 |
29 | try {
30 | // 等待两个线程的完成
31 | companyThread.join();
32 | bankThread.join();
33 | // 输出最后的余额
34 | System.out.printf("Account : Final Balance: %f\n", account.getBalance());
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/task/Account.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 帐户类,模拟一个银行帐户
5 | */
6 | public class Account {
7 | /**
8 | * 帐户余额
9 | */
10 | private double balance;
11 |
12 | /**
13 | * 获取帐户余额
14 | *
15 | * @return 帐户余额
16 | */
17 | public double getBalance() {
18 | return balance;
19 | }
20 |
21 | /**
22 | * 设置帐户余额
23 | *
24 | * @param balance 帐户余额
25 | */
26 | public void setBalance(double balance) {
27 | this.balance = balance;
28 | }
29 |
30 | /**
31 | * 增加帐户余额
32 | *
33 | * @param amount 增加的余额
34 | */
35 | public synchronized void addAccount(double amount) {
36 | double tmp = balance;
37 | try {
38 | Thread.sleep(10);
39 | } catch (InterruptedException e) {
40 | e.printStackTrace();
41 | }
42 |
43 | tmp += amount;
44 | balance = tmp;
45 | }
46 |
47 | /**
48 | * 减少帐户余额
49 | *
50 | * @param amount 减少的余额
51 | */
52 | public synchronized void subtractAmount(double amount) {
53 | double tmp = balance;
54 | try {
55 | Thread.sleep(10);
56 | } catch (InterruptedException e) {
57 | e.printStackTrace();
58 | }
59 |
60 | tmp -= amount;
61 | balance = tmp;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/task/Bank.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | public class Bank implements Runnable {
4 | /**
5 | * 一个帐户
6 | */
7 | private Account account;
8 |
9 | /**
10 | * 构造函数
11 | *
12 | * @param account 银行帐户
13 | */
14 | public Bank(Account account) {
15 | this.account = account;
16 | }
17 |
18 |
19 | @Override
20 | public void run() {
21 | for (int i = 0; i < 100; i++) {
22 | this.account.subtractAmount(1000);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/task/Company.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | public class Company implements Runnable {
4 |
5 | /**
6 | * 一个帐户
7 | */
8 | private Account account;
9 |
10 | /**
11 | * 构造函数
12 | * @param account 帐户对象
13 | */
14 | public Company(Account account) {
15 | this.account = account;
16 | }
17 |
18 | @Override
19 | public void run() {
20 | for (int i = 0; i < 100; i++) {
21 | this.account.addAccount(1000);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/02-03-使用非依赖属性实现同步/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Cinema;
4 | import com.concurrency.task.TicketOffice1;
5 | import com.concurrency.task.TicketOffice2;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建一个电影院对象
10 | Cinema cinema = new Cinema();
11 |
12 | // 创建一个出售一号影院厅票的售票窗口对象,并且让其在一个线程中运行
13 | TicketOffice1 ticketOffice1 = new TicketOffice1(cinema);
14 | Thread thread1 = new Thread(ticketOffice1, "TicketOffice1");
15 |
16 | // 创建一个出售二号影院厅票的售票窗口对象,并且让其在一个线程中运行
17 | TicketOffice2 ticketOffice2 = new TicketOffice2(cinema);
18 | Thread thread2 = new Thread(ticketOffice2, "TicketOffice2");
19 |
20 | // 启动两个售票窗口线程
21 | thread1.start();
22 | thread2.start();
23 |
24 | try {
25 | // 等待两个线程完成
26 | thread1.join();
27 | thread2.join();
28 | } catch (InterruptedException e) {
29 | e.printStackTrace();
30 | }
31 |
32 | // 输出电影院剩余的票数
33 | System.out.printf("Room 1 Vacancies: %d\n", cinema.getVacanciesCinema1());
34 | System.out.printf("Room 2 Vacancies: %d\n", cinema.getVacanciesCinema2());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/02-03-使用非依赖属性实现同步/src/com/concurrency/task/Cinema.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 影院类,其有两个影院厅
5 | */
6 | public class Cinema {
7 | /**
8 | * 保存影院厅1的剩余电影票数
9 | */
10 | private long vacanciesCinema1;
11 | /**
12 | * 保存影院厅2的剩余电影票数
13 | */
14 | private long vacanciesCinema2;
15 | /**
16 | * 控制vacanciesCinema1同步访问的对象
17 | */
18 | private final Object controlCinema1;
19 | /**
20 | * 控制 vacanciesCinema2同步访问的对象
21 | */
22 | private final Object controlCinema2;
23 |
24 | public Cinema() {
25 | controlCinema1 = new Object(); // 初始化同步控制变量
26 | controlCinema2 = new Object(); // 初始化同步控制变量
27 | vacanciesCinema1 = 20; // 设置初始空闲票数
28 | vacanciesCinema2 = 20; // 设置初始空闲票数
29 | }
30 |
31 | /**
32 | * 出售影院厅1的门票
33 | *
34 | * @param number 出售的门票张数
35 | * @return true出售成功,false出售失败
36 | */
37 | public boolean sellTickets1(int number) {
38 | synchronized (controlCinema1) {
39 | if (number < vacanciesCinema1) {
40 | vacanciesCinema1 -= number;
41 | return true;
42 | } else {
43 | return false;
44 | }
45 | }
46 | }
47 |
48 | /**
49 | * 出售影院厅2的门票
50 | *
51 | * @param number 出售的门票张数
52 | * @return true出售成功,false出售失败
53 | */
54 | public boolean sellTickets2(int number) {
55 | synchronized (controlCinema2) {
56 | if (number < vacanciesCinema2) {
57 | vacanciesCinema2 -= number;
58 | return true;
59 | } else {
60 | return false;
61 | }
62 | }
63 | }
64 |
65 | /**
66 | * 向售影院厅1退门票
67 | *
68 | * @param number 退的门票张数
69 | * @return true退票成功,总返回true
70 | */
71 | public boolean returnTickets1(int number) {
72 | synchronized (controlCinema1) {
73 | vacanciesCinema1 += number;
74 | return true;
75 | }
76 | }
77 |
78 | /**
79 | * 向售影院厅2退门票
80 | *
81 | * @param number 退的门票张数
82 | * @return true退票成功,总返回true
83 | */
84 | public boolean returnTickets2(int number) {
85 | synchronized (controlCinema2) {
86 | vacanciesCinema2 += number;
87 | return true;
88 | }
89 | }
90 |
91 | /**
92 | * 获取影院厅1剩余的门票数
93 | *
94 | * @return 影院1剩余的门票数
95 | */
96 | public long getVacanciesCinema1() {
97 | return vacanciesCinema1;
98 | }
99 |
100 | /**
101 | * 获取影院厅2剩余的门票数
102 | *
103 | * @return 影院2剩余的门票数
104 | */
105 | public long getVacanciesCinema2() {
106 | return vacanciesCinema2;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/02-03-使用非依赖属性实现同步/src/com/concurrency/task/TicketOffice1.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 售票窗口类,出售1号放映厅的票
5 | */
6 | public class TicketOffice1 implements Runnable {
7 | /**
8 | * 电影院对象
9 | */
10 | private Cinema cinema;
11 |
12 | /**
13 | * 构造函数
14 | * @param cinema 电影院对象
15 | */
16 | public TicketOffice1(Cinema cinema) {
17 | this.cinema = cinema;
18 | }
19 |
20 | @Override
21 | public void run() {
22 | cinema.sellTickets1(3);
23 | cinema.sellTickets1(2);
24 | cinema.sellTickets2(2);
25 | cinema.returnTickets1(3);
26 | cinema.sellTickets1(5);
27 | cinema.sellTickets2(2);
28 | cinema.sellTickets2(2);
29 | cinema.sellTickets2(2);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/02-03-使用非依赖属性实现同步/src/com/concurrency/task/TicketOffice2.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 售票窗口类,出售2号放映厅的票
5 | */
6 | public class TicketOffice2 implements Runnable {
7 | /**
8 | * 电影院对象
9 | */
10 | private Cinema cinema;
11 |
12 | /**
13 | * 构造函数
14 | *
15 | * @param cinema 电影院对象
16 | */
17 | public TicketOffice2(Cinema cinema) {
18 | this.cinema = cinema;
19 | }
20 |
21 | @Override
22 | public void run() {
23 | cinema.sellTickets2(2);
24 | cinema.sellTickets2(4);
25 | cinema.sellTickets1(2);
26 | cinema.sellTickets1(1);
27 | cinema.returnTickets2(2);
28 | cinema.sellTickets1(3);
29 | cinema.sellTickets2(2);
30 | cinema.sellTickets1(2);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/02-04-在同步代码中使用条件/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Consumer;
4 | import com.concurrency.task.EventStorage;
5 | import com.concurrency.task.Producer;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建一个事件存储对象
10 | EventStorage storage = new EventStorage();
11 |
12 | // 创建一个事件生产者对象,并且将其放入到一个线程中运行
13 | Producer producer = new Producer(storage);
14 | Thread thread1 = new Thread(producer);
15 |
16 | // 创建一个事件消费者对象,并且将其放入到一个线程中运行
17 | Consumer consumer = new Consumer(storage);
18 | Thread thread2 = new Thread(consumer);
19 |
20 | // 启动两线程
21 | thread2.start();
22 | thread1.start();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/02-04-在同步代码中使用条件/src/com/concurrency/task/Consumer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 消费者对象,消费事件
5 | */
6 | public class Consumer implements Runnable {
7 | /**
8 | * 事件存储对象
9 | */
10 | private EventStorage storage;
11 |
12 | /**
13 | * 构造函数
14 | *
15 | * @param storage 事件存储对象
16 | */
17 | public Consumer(EventStorage storage) {
18 | this.storage = storage;
19 | }
20 |
21 | @Override
22 | public void run() {
23 | for (int i = 0; i < 100; i++) {
24 | this.storage.get(); // 消费事件
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/02-04-在同步代码中使用条件/src/com/concurrency/task/EventStorage.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | /**
8 | * 事件存储类,生产者会存储事件,消费者会处理存储的事件,一个事件就是一个日期对象
9 | */
10 | public class EventStorage {
11 | /**
12 | * 最多可以保存的事件数
13 | */
14 | private int maxSize;
15 |
16 | /**
17 | * 存储事件的集合
18 | */
19 | private List storage;
20 |
21 | /**
22 | * 构造函数
23 | */
24 | public EventStorage() {
25 | this.maxSize = 10; // 最多可以存储10个事件
26 | this.storage = new LinkedList(); // 初始化事件存储集合
27 | }
28 |
29 | /**
30 | * 同步方法,向事件集合中添加一个事件
31 | */
32 | public synchronized void set() {
33 | while (this.storage.size() == this.maxSize) { // 如果集合已经满了,就等待
34 | try {
35 | wait();
36 | } catch (InterruptedException e) {
37 | e.printStackTrace();
38 | }
39 | }
40 |
41 | this.storage.add(new Date()); // 产生事件
42 | System.out.printf("Set: %d\n", storage.size());
43 | notify(); // 唤醒其它线程
44 | }
45 |
46 | /**
47 | * 同步方法,使用处理事件集合中的一个事件
48 | */
49 | public synchronized void get() {
50 | while (this.storage.size() == 0) { // 如果集合为空就等待
51 | try {
52 | wait();
53 | } catch (InterruptedException e) {
54 | e.printStackTrace();
55 | }
56 | }
57 |
58 | System.out.printf("Get: %d: %s\n", storage.size(), ((LinkedList>) storage).poll()); // 消费一个事件
59 | notify(); // 唤醒其它线程
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/02-04-在同步代码中使用条件/src/com/concurrency/task/Producer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 生产者对象,生产事件
5 | */
6 | public class Producer implements Runnable {
7 | /**
8 | * 事件存储对象
9 | */
10 | private EventStorage storage;
11 |
12 | /**
13 | * 构造函数
14 | *
15 | * @param storage 事件存储对象
16 | */
17 | public Producer(EventStorage storage) {
18 | this.storage = storage;
19 | }
20 |
21 | @Override
22 | public void run() {
23 | for (int i = 0; i < 100; i++) {
24 | this.storage.set(); // 产生事件
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/02-05-用锁实现同步/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Job;
4 | import com.concurrency.task.PrintQueue;
5 |
6 | public class Main {
7 | public static void main(String[] args) {
8 | // 创建一个打印队列
9 | PrintQueue printQueue = new PrintQueue();
10 |
11 | // 创建10个打印线程
12 | Thread thread[] = new Thread[10];
13 | for (int i = 0; i < 10; i++) {
14 | thread[i] = new Thread(new Job(printQueue), "Thread " + i);
15 | }
16 |
17 | // 启动线程
18 | for (int i = 0; i < 10; i++) {
19 | thread[i].start();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/02-05-用锁实现同步/src/com/concurrency/task/Job.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | public class Job implements Runnable {
4 | /**
5 | * 打印文档的队列
6 | */
7 | private PrintQueue printQueue;
8 |
9 | /**
10 | * 构造函数
11 | *
12 | * @param printQueue 打印文档的队列
13 | */
14 | public Job(PrintQueue printQueue) {
15 | this.printQueue = printQueue;
16 | }
17 |
18 | @Override
19 | public void run() {
20 | System.out.printf("%s: Going to print a document\n", Thread.currentThread().getName());
21 | printQueue.printJob(new Object());
22 | System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/02-05-用锁实现同步/src/com/concurrency/task/PrintQueue.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.locks.Lock;
4 | import java.util.concurrent.locks.ReentrantLock;
5 |
6 | /**
7 | * 打印队列类,模拟一个打印队列事件
8 | */
9 | public class PrintQueue {
10 | /**
11 | * 用于控制队列访问的锁
12 | */
13 | private final Lock queueLock = new ReentrantLock();
14 |
15 | /**
16 | * 打印一个文档
17 | *
18 | * @param object 要打印的文档对象
19 | */
20 | public void printJob(Object object) {
21 | queueLock.lock(); // 上锁
22 | try {
23 | long duration = (long) (Math.random() * 10000);
24 | System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000));
25 | Thread.sleep(duration);
26 | } catch (InterruptedException e) {
27 | e.printStackTrace();
28 | } finally {
29 | queueLock.unlock(); // 解锁
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/02-06-使用读写锁实现同步数据访问/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.PricesInfo;
4 | import com.concurrency.task.Reader;
5 | import com.concurrency.task.Writer;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建价格信息对象,用于存储价格
10 | PricesInfo pricesInfo = new PricesInfo();
11 |
12 | Reader readers[] = new Reader[5];
13 | Thread threadsReader[] = new Thread[5];
14 |
15 | // 创建5个读者并且将其放在不同的线程中远行
16 | for (int i = 0; i < 5; i++) {
17 | readers[i] = new Reader(pricesInfo);
18 | threadsReader[i] = new Thread(readers[i]);
19 | }
20 |
21 | // 创建一个写者,并且将其放在一个线程中运行
22 | Writer writer = new Writer(pricesInfo);
23 | Thread threadWriter = new Thread(writer);
24 |
25 | // 启动读者写者线程
26 | for (int i = 0; i < 5; i++) {
27 | threadsReader[i].start();
28 | }
29 | threadWriter.start();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/02-06-使用读写锁实现同步数据访问/src/com/concurrency/task/PricesInfo.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.locks.ReadWriteLock;
4 | import java.util.concurrent.locks.ReentrantReadWriteLock;
5 |
6 | /**
7 | * 价格信息类,这个类存储了两个价格,一个写者写这个价格,多个读者读这个价格
8 | */
9 | public class PricesInfo {
10 | /**
11 | * 两个价格g
12 | */
13 | private double price1;
14 | private double price2;
15 |
16 | /**
17 | * 控制价格访问的锁
18 | */
19 | private ReadWriteLock lock;
20 |
21 | /**
22 | * 构造函数,初始化价格和锁
23 | */
24 | public PricesInfo() {
25 | this.price1 = 1.0;
26 | this.price2 = 2.0;
27 | this.lock = new ReentrantReadWriteLock();
28 | }
29 |
30 | /**
31 | * 获取第一个价格
32 | *
33 | * @return 第一个价格
34 | */
35 | public double getPrice1() {
36 | lock.readLock().lock();
37 | double value = price1;
38 | lock.readLock().unlock();
39 | return value;
40 | }
41 |
42 | /**
43 | * 获取第二个价格
44 | *
45 | * @return 第二个价格
46 | */
47 | public double getPrice2() {
48 | lock.readLock().lock();
49 | double value = price2;
50 | lock.readLock().unlock();
51 | return value;
52 | }
53 |
54 | /**
55 | * 设置两个价格
56 | *
57 | * @param price1 第一个价格
58 | * @param price2 第二个价格
59 | */
60 | public void setPrices(double price1, double price2) {
61 | lock.writeLock().lock();
62 | this.price1 = price1;
63 | this.price2 = price2;
64 | lock.writeLock().unlock();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/02-06-使用读写锁实现同步数据访问/src/com/concurrency/task/Reader.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 读者类,消费价格
5 | */
6 | public class Reader implements Runnable {
7 | /**
8 | * 价格信息对象
9 | */
10 | private PricesInfo pricesInfo;
11 |
12 | /**
13 | * 构造函数
14 | *
15 | * @param pricesInfo 价格信息对象
16 | */
17 | public Reader(PricesInfo pricesInfo) {
18 | this.pricesInfo = pricesInfo;
19 | }
20 |
21 | /**
22 | * 核心方法,消费两个价格,并且将他们输出
23 | */
24 | @Override
25 | public void run() {
26 | for (int i = 0; i < 10; i++) {
27 | System.out.printf("%s: Price 1: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice1());
28 | System.out.printf("%s: Price 2: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice2());
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/02-06-使用读写锁实现同步数据访问/src/com/concurrency/task/Writer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 写者类,产生价格
5 | */
6 | public class Writer implements Runnable {
7 | /**
8 | * 价格信息对象
9 | */
10 | private PricesInfo pricesInfo;
11 |
12 | /**
13 | * 构造函数
14 | *
15 | * @param pricesInfo 价格信息对象
16 | */
17 | public Writer(PricesInfo pricesInfo) {
18 | this.pricesInfo = pricesInfo;
19 | }
20 |
21 | /**
22 | * 核心方法,写价格
23 | */
24 | @Override
25 | public void run() {
26 | for (int i = 0; i < 3; i++) {
27 | System.out.printf("Writer: Attempt to modify the prices.\n");
28 | pricesInfo.setPrices(Math.random() * 10, Math.random() * 8);
29 | System.out.printf("Writer: Prices have been modified.\n");
30 | try {
31 | Thread.sleep(2);
32 | } catch (InterruptedException e) {
33 | e.printStackTrace();
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/02-07-修改锁的公平性/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Job;
4 | import com.concurrency.task.PrintQueue;
5 |
6 | public class Main {
7 | public static void main(String[] args) {
8 | // 创建一个打印队列
9 | PrintQueue printQueue = new PrintQueue();
10 |
11 | // 创建10个打印任务并且将其放入到不同的线程中运行
12 | Thread thread[] = new Thread[10];
13 | for (int i = 0; i < 10; i++) {
14 | thread[i] = new Thread(new Job(printQueue), "Thread " + i);
15 | }
16 |
17 | // 每隔0.1s运行一个线程,一个10个线程
18 | for (int i = 0; i < 10; i++) {
19 | thread[i].start();
20 | try {
21 | Thread.sleep(100);
22 | } catch (InterruptedException e) {
23 | e.printStackTrace();
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/02-07-修改锁的公平性/src/com/concurrency/task/Job.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 |
4 | public class Job implements Runnable {
5 | /**
6 | * 打印文档的队列
7 | */
8 | private PrintQueue printQueue;
9 |
10 | /**
11 | * 构造函数
12 | *
13 | * @param printQueue 打印文档的队列
14 | */
15 | public Job(PrintQueue printQueue) {
16 | this.printQueue = printQueue;
17 | }
18 |
19 | @Override
20 | public void run() {
21 | System.out.printf("%s: Going to print a document\n", Thread.currentThread().getName());
22 | printQueue.printJob(new Object());
23 | System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/02-07-修改锁的公平性/src/com/concurrency/task/PrintQueue.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.locks.Lock;
4 | import java.util.concurrent.locks.ReentrantLock;
5 |
6 | /**
7 | * 打印队列类,模拟一个打印队列事件
8 | */
9 | public class PrintQueue {
10 | /**
11 | * 用于控制队列访问的锁,使用公平锁
12 | */
13 | private final Lock queueLock = new ReentrantLock(false);
14 |
15 | /**
16 | * 打印一个文档
17 | *
18 | * @param object 要打印的文档对象
19 | */
20 | public void printJob(Object object) {
21 | queueLock.lock(); // 上锁
22 | try {
23 | long duration = (long) (Math.random() * 10000);
24 | System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000));
25 | Thread.sleep(duration);
26 | } catch (InterruptedException e) {
27 | e.printStackTrace();
28 | } finally {
29 | queueLock.unlock(); // 解锁
30 | }
31 |
32 | queueLock.lock(); // 上锁
33 | try {
34 | long duration = (long) (Math.random() * 10000);
35 | System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000));
36 | Thread.sleep(duration);
37 | } catch (InterruptedException e) {
38 | e.printStackTrace();
39 | } finally {
40 | queueLock.unlock(); // 解锁
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/02-08-在锁中使用多条件/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Consumer;
4 | import com.concurrency.task.Producer;
5 | import com.concurrency.utils.Buffer;
6 | import com.concurrency.utils.FileMock;
7 |
8 | public class Main {
9 | public static void main(String[] args) {
10 | // 创建一个文件模拟对象,它有101行
11 | FileMock mock = new FileMock(101, 10);
12 |
13 | // 创建一个缓冲对象,最多可以缓存20行数据
14 | Buffer buffer = new Buffer(20);
15 |
16 | // 创建一个生产者对象,并且让它在一个单独的线程中运行
17 | Producer producer = new Producer(mock, buffer);
18 | Thread threadProducer = new Thread(producer, "Producer");
19 |
20 | // 创建三个消费者对象,并且个他们分别在不同的线程中运行
21 | Consumer consumers[] = new Consumer[3];
22 | Thread threadConsumers[] = new Thread[3];
23 |
24 | for (int i = 0; i < 3; i++) {
25 | consumers[i] = new Consumer(buffer);
26 | threadConsumers[i] = new Thread(consumers[i], "Consumer " + i);
27 | }
28 |
29 | // 启动生产者和消费者线程
30 | threadProducer.start();
31 | for (int i = 0; i < 3; i++) {
32 | threadConsumers[i].start();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/02-08-在锁中使用多条件/src/com/concurrency/task/Consumer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.utils.Buffer;
4 |
5 | import java.util.Random;
6 |
7 | public class Consumer implements Runnable {
8 | /**
9 | * 缓冲对象
10 | */
11 | private Buffer buffer;
12 |
13 | /**
14 | * 构造函数
15 | *
16 | * @param buffer 缓冲对象
17 | */
18 | public Consumer(Buffer buffer) {
19 | this.buffer = buffer;
20 | }
21 |
22 | /**
23 | * 核心方法,当缓冲中有数据时就进行处理
24 | */
25 | @Override
26 | public void run() {
27 | while (buffer.hasPendingLines()) {
28 | String line = buffer.get();
29 | processLine(line);
30 | }
31 | }
32 |
33 | /**
34 | * 模拟处理一行数据,休眠[0,100)毫秒
35 | *
36 | * @param line 一行数据
37 | */
38 | private void processLine(String line) {
39 | try {
40 | Random random = new Random();
41 | Thread.sleep(random.nextInt(100));
42 | } catch (InterruptedException e) {
43 | e.printStackTrace();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/02-08-在锁中使用多条件/src/com/concurrency/task/Producer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.utils.Buffer;
4 | import com.concurrency.utils.FileMock;
5 |
6 | public class Producer implements Runnable {
7 | /**
8 | * 文件模拟对象
9 | */
10 | private FileMock mock;
11 | /**
12 | * 缓冲对象
13 | */
14 | private Buffer buffer;
15 |
16 | /**
17 | * 构造函数
18 | *
19 | * @param mock 文件模拟对象
20 | * @param buffer 缓冲对象
21 | */
22 | public Producer(FileMock mock, Buffer buffer) {
23 | this.mock = mock;
24 | this.buffer = buffer;
25 | }
26 |
27 | /**
28 | * 核心方法,读取文件中的数据,并且将读取到的数据插入到缓冲区
29 | */
30 | @Override
31 | public void run() {
32 | this.buffer.setPendingLines(true);
33 | while (this.mock.hasMoreLines()) {
34 | String line = this.mock.getLine();
35 | this.buffer.insert(line);
36 | }
37 | this.buffer.setPendingLines(false);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/02-08-在锁中使用多条件/src/com/concurrency/utils/Buffer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.utils;
2 |
3 | import java.util.LinkedList;
4 | import java.util.concurrent.locks.Condition;
5 | import java.util.concurrent.locks.ReentrantLock;
6 |
7 | public class Buffer {
8 | /**
9 | * 集合对象,被当作缓冲使用
10 | */
11 | private LinkedList buffer;
12 | /**
13 | * 缓冲的最大大小
14 | */
15 | private int maxSize;
16 | /**
17 | * 控制缓冲访问的锁
18 | */
19 | private ReentrantLock lock;
20 | /**
21 | * 缓冲中有数据的条件
22 | */
23 | private Condition lines;
24 | /**
25 | * 缓冲为空的条件
26 | */
27 | private Condition space;
28 | /**
29 | * 是否追加行
30 | */
31 | private boolean pendingLines;
32 |
33 | /**
34 | * 构造函数,初始化属性
35 | *
36 | * @param maxSize 缓冲最大大小
37 | */
38 | public Buffer(int maxSize) {
39 | this.maxSize = maxSize;
40 | this.buffer = new LinkedList<>();
41 | this.lock = new ReentrantLock();
42 | this.lines = lock.newCondition();
43 | this.space = lock.newCondition();
44 | this.pendingLines = true;
45 | }
46 |
47 | /**
48 | * 向缓冲区中插入一行数据
49 | *
50 | * @param line 一行数据
51 | */
52 | public void insert(String line) {
53 | lock.lock();
54 | try {
55 | while (this.buffer.size() == this.maxSize) {
56 | this.space.await();
57 | }
58 |
59 | this.buffer.offer(line);
60 | System.out.printf("%s: Inserted Line: %d\n", Thread.currentThread().getName(), this.buffer.size());
61 | this.lines.signalAll();
62 | } catch (InterruptedException e) {
63 | e.printStackTrace();
64 | } finally {
65 | lock.unlock();
66 | }
67 | }
68 |
69 | public String get() {
70 | String line = null;
71 | lock.lock();
72 | try {
73 | while (this.buffer.size() == 0 && hasPendingLines()) {
74 | this.lines.await();
75 | }
76 |
77 | if (hasPendingLines()) {
78 | line = this.buffer.poll();
79 | System.out.printf("%s: Line Readed: %d\n", Thread.currentThread().getName(), this.buffer.size());
80 | this.space.signalAll();
81 | }
82 |
83 | } catch (InterruptedException e) {
84 | e.printStackTrace();
85 | } finally {
86 | this.lock.unlock();
87 | }
88 |
89 | return line;
90 | }
91 |
92 | /**
93 | * 设置是否追加行
94 | *
95 | * @param pendingLines true追加,false不追加
96 | */
97 | public void setPendingLines(boolean pendingLines) {
98 | this.pendingLines = pendingLines;
99 | }
100 |
101 | /**
102 | * 判断是否有数据可以进行处理
103 | *
104 | * @return true有数据可进行处理,false无数据可以进行处理
105 | */
106 | public boolean hasPendingLines() {
107 | return this.pendingLines || this.buffer.size() > 0;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/02-08-在锁中使用多条件/src/com/concurrency/utils/FileMock.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.utils;
2 |
3 | /**
4 | * 文件模拟类,
5 | */
6 | public class FileMock {
7 | /**
8 | * 模拟文件的内容
9 | */
10 | private String[] content;
11 | /**
12 | * 当前需要处理的文件第多少行
13 | */
14 | private int index;
15 |
16 | /**
17 | * 构造函数,随机生成文件的内容
18 | *
19 | * @param size 文件的行数
20 | * @param length 每行文件的字符数
21 | */
22 | public FileMock(int size, int length) {
23 | this.content = new String[size];
24 | for (int i = 0; i < size; i++) {
25 | StringBuilder builder = new StringBuilder(length);
26 | for (int j = 0; j < length; j++) {
27 | int indice = (int) (Math.random() * 255);
28 | builder.append((char) indice);
29 | }
30 | content[i] = builder.toString();
31 | }
32 | this.index = 0;
33 | }
34 |
35 | /**
36 | * 判断是否还有文件的行数需要处理
37 | *
38 | * @return true是,false否
39 | */
40 | public boolean hasMoreLines() {
41 | return this.index < this.content.length;
42 | }
43 |
44 | /**
45 | * 返回下一行的文件内容
46 | *
47 | * @return 有返回文件内容,没有返回false
48 | */
49 | public String getLine() {
50 | if (this.hasMoreLines()) {
51 | System.out.println("Mock: " + (this.content.length - this.index));
52 | return this.content[this.index++];
53 | }
54 | return null;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/02-09-应用例子/src/com.concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.BuildStats;
4 | import com.concurrency.task.Sensor1;
5 | import com.concurrency.task.Sensor2;
6 |
7 | import java.util.Date;
8 |
9 | /**
10 | * Author: 王俊超
11 | * Date: 2014-11-23
12 | * Time: 08:38
13 | * Declaration: All Rights Reserved !!!
14 | */
15 | public class Main {
16 | public static void main(String[] args) {
17 | // 创建一个建筑物状态对象
18 | BuildStats stats = new BuildStats();
19 |
20 | // 创建场景1对象,并且让它在一个单独的线程中运行
21 | Sensor1 sensor1 = new Sensor1(stats);
22 | Thread thread1 = new Thread(sensor1, "Sensor 1");
23 |
24 | // 创建场景2对象,并且让它在一个单独的线程中运行
25 | Sensor2 sensor2 = new Sensor2(stats);
26 | Thread thread2 = new Thread(sensor2, "Sensor 2");
27 |
28 | // 获取实际时间
29 | Date date1 = new Date();
30 |
31 | // 启动线程
32 | thread1.start();
33 | thread2.start();
34 |
35 | try {
36 | // 等待线程完成
37 | thread1.join();
38 | thread2.join();
39 | } catch (InterruptedException e) {
40 | e.printStackTrace();
41 | }
42 |
43 | // 获取实际时间,并且输出实际时间
44 | Date date2 = new Date();
45 | stats.printStats();
46 | System.out.println("Execution Time: " + ((date2.getTime() - date1.getTime()) / 1000));
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/02-09-应用例子/src/com.concurrency/task/BuildStats.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * 建筑物状态类,对进入其中的人进行统计,并且控制建筑物中的人数
7 | * Author: 王俊超
8 | * Date: 2014-11-25
9 | * Time: 07:51
10 | * Declaration: All Rights Reserved !!!
11 | */
12 | public class BuildStats {
13 | /**
14 | * 建筑物中的人数
15 | */
16 | private long numPeople;
17 |
18 | /**
19 | * 模拟人进入到建筑物中
20 | */
21 | public void comeIn() {
22 | System.out.printf("%s: A person enters.\n", Thread.currentThread().getName());
23 | synchronized (this) {
24 | numPeople++;
25 | }
26 | generateCard();
27 | }
28 |
29 | /**
30 | * 模拟人从建筑物中走出来
31 | */
32 | public void goOut() {
33 | System.out.printf("%s: A person leaves.\n", Thread.currentThread().getName());
34 | synchronized (this) {
35 | numPeople--;
36 | }
37 | generateReport();
38 | }
39 |
40 | /**
41 | * 当人进入建筑物中时,会模拟产生一张卡
42 | */
43 | private void generateCard() {
44 | try {
45 | TimeUnit.SECONDS.sleep(3);
46 | } catch (InterruptedException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 |
51 | /**
52 | * 当人离开建筑物时,会模拟产生一个报告
53 | */
54 | private void generateReport() {
55 | try {
56 | TimeUnit.SECONDS.sleep(2);
57 | } catch (InterruptedException e) {
58 | e.printStackTrace();
59 | }
60 | }
61 |
62 | /**
63 | * 输入建筑物中的人数
64 | */
65 | public void printStats() {
66 | System.out.printf("%d persons in the building.\n", numPeople);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/02-09-应用例子/src/com.concurrency/task/Sensor1.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * Author: 王俊超
5 | * Date: 2014-11-25
6 | * Time: 07:59
7 | * Declaration: All Rights Reserved !!!
8 | */
9 | public class Sensor1 implements Runnable {
10 | /**
11 | * 建筑物状态对象
12 | */
13 | private BuildStats stats;
14 |
15 | /**
16 | * 构造函数
17 | *
18 | * @param stats 建筑物状态对象
19 | */
20 | public Sensor1(BuildStats stats) {
21 | this.stats = stats;
22 | }
23 |
24 | /**
25 | * 核心方法,模拟人在建筑物中的进出
26 | */
27 | @Override
28 | public void run() {
29 | stats.comeIn();
30 | stats.comeIn();
31 | stats.comeIn();
32 | stats.goOut();
33 | stats.comeIn();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/02-09-应用例子/src/com.concurrency/task/Sensor2.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * Author: 王俊超
5 | * Date: 2014-11-25
6 | * Time: 07:59
7 | * Declaration: All Rights Reserved !!!
8 | */
9 | public class Sensor2 implements Runnable {
10 | /**
11 | * 建筑物状态对象
12 | */
13 | private BuildStats stats;
14 |
15 | /**
16 | * 构造函数
17 | *
18 | * @param stats 建筑物状态对象
19 | */
20 | public Sensor2(BuildStats stats) {
21 | this.stats = stats;
22 | }
23 |
24 | /**
25 | * 核心方法,模拟人在建筑物中的进出
26 | */
27 | @Override
28 | public void run() {
29 | stats.comeIn();
30 | stats.comeIn();
31 | stats.goOut();
32 | stats.goOut();
33 | stats.goOut();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/03-02-资源并发控制访问/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Job;
4 | import com.concurrency.task.PrintQueue;
5 |
6 | public class Main {
7 | public static void main(String[] args) {
8 | // 创建一个打印队列对象
9 | PrintQueue printQueue = new PrintQueue();
10 |
11 | // 创建10个线程
12 | Thread thread[] = new Thread[10];
13 | for (int i = 0; i < 10; i++) {
14 | thread[i] = new Thread(new Job(printQueue), "Thread " + i);
15 | }
16 |
17 | // 启动10个线程
18 | for (int i = 0; i < 10; i++) {
19 | thread[i].start();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/03-02-资源并发控制访问/src/com/concurrency/task/Job.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | public class Job implements Runnable {
4 | /**
5 | * 打印队列对象
6 | */
7 | private PrintQueue printQueue;
8 |
9 | /**
10 | * 构造函数,初始化打印队列对象
11 | *
12 | * @param printQueue 打印队列对象
13 | */
14 | public Job(PrintQueue printQueue) {
15 | this.printQueue = printQueue;
16 | }
17 |
18 | /**
19 | * 核心方法,向打印队列中发送打印任务,并且等待它完成
20 | */
21 | @Override
22 | public void run() {
23 | System.out.printf("%s: Going to print a job\n", Thread.currentThread().getName());
24 | printQueue.printJob(new Object());
25 | System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/03-02-资源并发控制访问/src/com/concurrency/task/PrintQueue.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.core.Main;
4 |
5 | import java.util.concurrent.Semaphore;
6 | import java.util.concurrent.TimeUnit;
7 |
8 | /**
9 | * 打印队列类,使用信号量来控制打钱作业的访问
10 | */
11 | public class PrintQueue {
12 | /**
13 | * 信号量,控制队列的访问
14 | */
15 | private final Semaphore semaphore;
16 |
17 | /**
18 | * 构造函数,初始化信号量
19 | */
20 | public PrintQueue() {
21 | semaphore = new Semaphore(1);
22 | }
23 |
24 | /**
25 | * 模拟文档打印的方法
26 | *
27 | * @param document 需要打印的对象
28 | */
29 | public void printJob(Object document) {
30 | try {
31 | // 请求信号量,如果已经被其它线程请求过,则当前请求的线程会休眠,直到获得这个信号量
32 | semaphore.acquire();
33 |
34 | long duration = (long) (Math.random() * 10);
35 | System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), duration);
36 | Thread.sleep(duration);
37 | TimeUnit.SECONDS.sleep(duration);
38 | } catch (InterruptedException e) {
39 | e.printStackTrace();
40 | } finally {
41 | // 释放信号量,如果有其它的线程在请求这个信号量,JVN会选择其中的某一个程获取信号量,让其运行
42 | semaphore.release();
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/03-03-资源的多副本的并发访问控制/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Job;
4 | import com.concurrency.task.PrintQueue;
5 |
6 | public class Main {
7 | public static void main(String[] args) {
8 | // 创建一个打印对队对象
9 | PrintQueue printQueue = new PrintQueue();
10 |
11 | // 创建12个线程,运行作业任务,这些任务都向同一个打印队列对象发出打印请求
12 | Thread thread[] = new Thread[12];
13 | for (int i = 0; i < 12; i++) {
14 | thread[i] = new Thread(new Job(printQueue), "Thread " + i);
15 | }
16 |
17 | // 启动12个线程
18 | for (int i = 0; i < 12; i++) {
19 | thread[i].start();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/03-03-资源的多副本的并发访问控制/src/com/concurrency/task/Job.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | public class Job implements Runnable {
4 | /**
5 | * 打印队列对象
6 | */
7 | private PrintQueue printQueue;
8 |
9 | /**
10 | * 构造函数,初始化打印队列对象
11 | *
12 | * @param printQueue 打印队列对象
13 | */
14 | public Job(PrintQueue printQueue) {
15 | this.printQueue = printQueue;
16 | }
17 |
18 | /**
19 | * 核心方法,向打印队列中发送打印任务,并且等待它完成
20 | */
21 | @Override
22 | public void run() {
23 | System.out.printf("%s: Going to print a job\n", Thread.currentThread().getName());
24 | printQueue.printJob(new Object());
25 | System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/03-03-资源的多副本的并发访问控制/src/com/concurrency/task/PrintQueue.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Semaphore;
4 | import java.util.concurrent.TimeUnit;
5 | import java.util.concurrent.locks.Lock;
6 | import java.util.concurrent.locks.ReentrantLock;
7 |
8 | /**
9 | * 打印队列对象,它可以访问三台打印机,使用信号量来控制打印机的访问,当有一个打印作业,
10 | * 如果有空闲的打印杨就将作业分配到某个打印机上,否则就等待打印机空闲,再分配打印机
11 | */
12 | public class PrintQueue {
13 | /**
14 | * 资源信号量,控制打印机的访问
15 | */
16 | private Semaphore semaphore;
17 | /**
18 | * 标记打印机是否空闲的数组
19 | */
20 | private boolean[] freePrinters;
21 | /**
22 | * 锁,控制打印机是否空闲的数组的访问
23 | */
24 | private Lock lockPrinters;
25 |
26 | /**
27 | * 构造函数,初始化变量
28 | */
29 | public PrintQueue() {
30 | semaphore = new Semaphore(3); // 资源信号量的个数为3,说明有3个打印机
31 | freePrinters = new boolean[3];
32 | for (int i = 0; i < freePrinters.length; i++) {
33 | freePrinters[i] = true;
34 | }
35 |
36 | lockPrinters = new ReentrantLock();
37 | }
38 |
39 | /**
40 | * 模拟文档打印的方法
41 | *
42 | * @param document 需要打印的对象
43 | */
44 | public void printJob(Object document) {
45 | try {
46 | // 请求信号量,如果有一个打印机是空闲的,就会访问其中一个空闲的打印机
47 | semaphore.acquire();
48 |
49 | // 获取分配的打印机编号
50 | int assignedPrinter = getPrinter();
51 |
52 | Long duration = (long) (Math.random() * 10);
53 | System.out.printf("%s: PrintQueue: Printing a Job in Printer %d during %d seconds\n", Thread.currentThread().getName(), assignedPrinter, duration);
54 | TimeUnit.SECONDS.sleep(duration);
55 |
56 | // 释放打印机
57 | freePrinters[assignedPrinter] = true;
58 | } catch (InterruptedException e) {
59 | e.printStackTrace();
60 | } finally {
61 | // 释放信号量
62 | semaphore.release();
63 | }
64 | }
65 |
66 | /**
67 | * 获取分配的打印机编号
68 | * @return 分配的打印机编号
69 | */
70 | private int getPrinter() {
71 | int ret = -1;
72 | try {
73 | // 获取打印机状态数组的访问能力
74 | lockPrinters.lock();
75 | // 查找第一个空闲的打印机
76 | for (int i = 0; i < freePrinters.length; i++) {
77 | if (freePrinters[i]) {
78 | ret = i;
79 | freePrinters[i] = false;
80 | break;
81 | }
82 | }
83 | } catch (Exception e) {
84 | e.printStackTrace();
85 | } finally {
86 | // 释放打印机状态数组的访问能力
87 | lockPrinters.unlock();
88 | }
89 | return ret;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/03-04-等待多个并发事件的完成/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Participant;
4 | import com.concurrency.task.VideoConference;
5 |
6 | public class Main {
7 | public static void main(String[] args) {
8 | // 创建一个视频会议对象,它有10个参与者
9 | VideoConference conference = new VideoConference(10);
10 | // 创建一个线程去运行视频会议
11 | Thread threadConference = new Thread(conference);
12 | threadConference.start();
13 |
14 | // 创建十个参与者,每个参与者在一个单独的线程中运行
15 | for (int i = 0; i < 10; i++) {
16 | Participant p = new Participant(conference, "Participant " + i);
17 | Thread t = new Thread(p);
18 | t.start();
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/03-04-等待多个并发事件的完成/src/com/concurrency/task/Participant.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * 参与者类
7 | */
8 | public class Participant implements Runnable {
9 | /**
10 | * 视频会议对象
11 | */
12 | private VideoConference conference;
13 | /**
14 | * 参与者的名称(仅仅是为了记录使用)
15 | */
16 | private String name;
17 |
18 | /**
19 | * 构造函数
20 | *
21 | * @param conference 视频会议对象
22 | * @param name 参与者的名称
23 | */
24 | public Participant(VideoConference conference, String name) {
25 | this.conference = conference;
26 | this.name = name;
27 | }
28 |
29 |
30 | /**
31 | * 核心方法,等待一个随机时间就进入视频会议
32 | */
33 | @Override
34 | public void run() {
35 | long duration = (long) (Math.random() * 10);
36 | try {
37 | TimeUnit.SECONDS.sleep(duration);
38 | } catch (InterruptedException e) {
39 | e.printStackTrace();
40 | }
41 | conference.arrive(name);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/03-04-等待多个并发事件的完成/src/com/concurrency/task/VideoConference.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.CountDownLatch;
4 |
5 | /**
6 | * 视频会类
7 | * 使用倒计时闩来控制所有参与者都到达后才发生事件
8 | */
9 | public class VideoConference implements Runnable {
10 | /**
11 | * 倒计时闩对象
12 | */
13 | private final CountDownLatch controller;
14 |
15 | /**
16 | * 构造函数,初始化倒计时闩
17 | * @param number 参与者人数
18 | */
19 | public VideoConference(int number) {
20 | controller = new CountDownLatch(number);
21 | }
22 |
23 | /**
24 | * 每个参与到视频会议的都会调用此方法
25 | * @param name 参与者
26 | */
27 | public void arrive(String name) {
28 | System.out.printf("%s has arrived.\n", name);
29 | controller.countDown();
30 | System.out.printf("VideoConference: Waiting for %d participants.\n", controller.getCount());
31 | }
32 |
33 | /**
34 | * 核心方法,当所有参与者都到达了,就开始视频仁义
35 | */
36 | @Override
37 | public void run() {
38 | System.out.printf("VideoConference: Initialization: %d participants.\n", controller.getCount());
39 | try {
40 | // Wait for all the participants
41 | controller.await();
42 | // Starts the conference
43 | System.out.printf("VideoConference: All the participants have come\n");
44 | System.out.printf("VideoConference: Let's start...\n");
45 | } catch (InterruptedException e) {
46 | e.printStackTrace();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/03-05-在集合点的同步/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Grouper;
4 | import com.concurrency.task.Searcher;
5 | import com.concurrency.utils.MatrixMock;
6 | import com.concurrency.utils.Results;
7 |
8 | import java.util.concurrent.CyclicBarrier;
9 |
10 | public class Main {
11 | public static void main(String[] args) {
12 |
13 | final int ROWS = 10000; // 矩阵的行数
14 | final int NUMBERS = 1000; // 矩阵的列数
15 | final int SEARCH = 5; // 要查询的数字
16 | final int PARTICIPANTS = 5; // 查询线程的个数
17 | final int LINES_PARTICIPANT = 2000; // 每个查询线程处理的行数
18 | MatrixMock mock = new MatrixMock(ROWS, NUMBERS, SEARCH); // 创建矩阵模拟对象
19 | Results results = new Results(ROWS); // 创建结果对象
20 | Grouper grouper = new Grouper(results); // 创建组合对象
21 |
22 | // 创建一个同步栅对象,它有5个参与者, 5个参与者线程完成后,会调用grouper中的run方法
23 | CyclicBarrier barrier = new CyclicBarrier(PARTICIPANTS, grouper);
24 |
25 | // 创建5个参与者对象,并且让它们各自在单独的线程中运行
26 | Searcher[] searchers = new Searcher[PARTICIPANTS];
27 | for (int i = 0; i < searchers.length; i++) {
28 | searchers[i] = new Searcher(barrier, i * LINES_PARTICIPANT, (i * LINES_PARTICIPANT) + LINES_PARTICIPANT,
29 | mock, results, PARTICIPANTS);
30 |
31 | Thread thread = new Thread(searchers[i]);
32 | thread.start();
33 | }
34 | System.out.printf("Main: The main thread has finished.\n");
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/03-05-在集合点的同步/src/com/concurrency/task/Grouper.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.utils.Results;
4 |
5 | /**
6 | * 组合类,汇总查找的结果
7 | */
8 | public class Grouper implements Runnable {
9 | /**
10 | * 结果对象
11 | */
12 | private Results results;
13 |
14 | /**
15 | * 构造函数
16 | *
17 | * @param results 结果对象
18 | */
19 | public Grouper(Results results) {
20 | this.results = results;
21 | }
22 |
23 | /**
24 | * 核心方法,对查找的结果进行汇总
25 | */
26 | @Override
27 | public void run() {
28 | int finalResult = 0;
29 | System.out.printf("Grouper: Processing results...\n");
30 | int data[] = results.getData();
31 | for (int number : data) {
32 | finalResult += number;
33 | }
34 | System.out.printf("Grouper: Total result: %d.\n", finalResult);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/03-05-在集合点的同步/src/com/concurrency/task/Searcher.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.utils.MatrixMock;
4 | import com.concurrency.utils.Results;
5 |
6 | import java.util.concurrent.BrokenBarrierException;
7 | import java.util.concurrent.CyclicBarrier;
8 |
9 | /**
10 | * 查找类
11 | */
12 | public class Searcher implements Runnable {
13 | /**
14 | * 开始查找的行数
15 | */
16 | private int firstRow;
17 | /**
18 | * 最后查找的行数(不包含)
19 | */
20 | private int lastRow;
21 | /**
22 | * 矩阵模拟对象
23 | */
24 | private MatrixMock mock;
25 | /**
26 | * 结果对象
27 | */
28 | private Results results;
29 | /**
30 | * 要查找的数字
31 | */
32 | private int number;
33 | /**
34 | * 同步栅
35 | */
36 | private final CyclicBarrier barrier;
37 |
38 | /**
39 | * 构造函数
40 | *
41 | * @param barrier 同步栅
42 | * @param firstRow 开始查找的行数
43 | * @param lastRow 最后查找的行数(不包含)
44 | * @param mock 矩阵模拟对象
45 | * @param results 结果对象
46 | * @param number 要查找的数字
47 | */
48 | public Searcher(CyclicBarrier barrier, int firstRow, int lastRow, MatrixMock mock, Results results, int number) {
49 | this.barrier = barrier;
50 | this.firstRow = firstRow;
51 | this.lastRow = lastRow;
52 | this.mock = mock;
53 | this.results = results;
54 | this.number = number;
55 | }
56 |
57 | /**
58 | * 核心方法,查找指定行数范围内的指定数字,将结果保存在结果数组对应的位置
59 | */
60 | @Override
61 | public void run() {
62 | int counter;
63 | System.out.printf("%s: Processing lines from %d to %d.\n", Thread.currentThread().getName(), firstRow, lastRow);
64 | for (int i = firstRow; i < lastRow; i++) {
65 | int row[] = mock.getRow(i);
66 | counter = 0;
67 | for (int j = 0; j < row.length; j++) {
68 | if (row[j] == number) {
69 | counter++;
70 | }
71 | }
72 |
73 | results.setData(i, counter);
74 | }
75 |
76 | System.out.printf("%s: Lines processed.\n", Thread.currentThread().getName());
77 | try {
78 | barrier.await(); // 等待所有查找完成
79 | } catch (InterruptedException e) {
80 | e.printStackTrace();
81 | } catch (BrokenBarrierException e) {
82 | e.printStackTrace();
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/03-05-在集合点的同步/src/com/concurrency/utils/MatrixMock.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.utils;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * 矩阵模拟类,随机生成0-9之间数字二维矩
7 | */
8 | public class MatrixMock {
9 | /**
10 | * 0-9之间数字二维矩阵
11 | */
12 | private int[][] data;
13 |
14 | /**
15 | * 构造函数
16 | *
17 | * @param size 矩阵的行数
18 | * @param length 每行的长度
19 | * @param number 要查找的数字
20 | */
21 | public MatrixMock(int size, int length, int number) {
22 | int counter = 0;
23 | data = new int[size][length];
24 | Random random = new Random();
25 | for (int i = 0; i < size; i++) {
26 | for (int j = 0; j < length; j++) {
27 | data[i][j] = random.nextInt(10);
28 | if (data[i][j] == number) {
29 | counter++;
30 | }
31 | }
32 | }
33 |
34 | System.out.printf("Mock: There are %d ocurrences of number in generated data.\n", counter, number);
35 | }
36 |
37 | /**
38 | * 获取行row行数据
39 | *
40 | * @param row 行数
41 | * @return 第row行数据,没有就返回null
42 | */
43 | public int[] getRow(int row) {
44 | if (row >= 0 && row < data.length) {
45 | return data[row];
46 | }
47 |
48 | return null;
49 | }
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/03-05-在集合点的同步/src/com/concurrency/utils/Results.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.utils;
2 |
3 | /**
4 | * 结果类,保存矩阵中每行找到指定数字的次数
5 | */
6 | public class Results {
7 | /**
8 | * 保存矩阵中每行找到指定数字的次数
9 | */
10 | private int[] data;
11 |
12 | /**
13 | * 构造函数
14 | *
15 | * @param size 数组长度
16 | */
17 | public Results(int size) {
18 | this.data = new int[size];
19 | }
20 |
21 | /**
22 | * 设置数组的值
23 | *
24 | * @param position 位置
25 | * @param value 要设置的值
26 | */
27 | public void setData(int position, int value) {
28 | data[position] = value;
29 | }
30 |
31 | /**
32 | * 获取保存的数据
33 | *
34 | * @return 保存的数据
35 | */
36 | public int[] getData() {
37 | return data;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/03-06-并发阶段任务的运行/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.FileSearch;
4 |
5 | import java.util.concurrent.Phaser;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建一个阶段对象,它有三个参与者
10 | Phaser phaser = new Phaser(3);
11 |
12 | // 创建一个文件搜索对象,每一个搜索不同的目录
13 | FileSearch system = new FileSearch("C:\\Windows", "log", phaser);
14 | FileSearch apps = new FileSearch("C:\\Program Files", "log", phaser);
15 | FileSearch documents = new FileSearch("C:\\Documents And Settings", "log", phaser);
16 |
17 | // 创建一个线程运行文件搜索对象,并且启动线程
18 | Thread systemThread = new Thread(system, "System");
19 | systemThread.start();
20 |
21 | // 创建一个线程运行文件搜索对象,并且启动线程
22 | Thread appsThread = new Thread(apps, "Apps");
23 | appsThread.start();
24 |
25 | // 创建一个线程运行文件搜索对象,并且启动线程
26 | Thread documentsThread = new Thread(documents, "Documents");
27 | documentsThread.start();
28 |
29 | // 等待所有的线程都结束
30 | try {
31 | systemThread.join();
32 | appsThread.join();
33 | documentsThread.join();
34 | } catch (InterruptedException e) {
35 | e.printStackTrace();
36 | }
37 |
38 | System.out.printf("Terminated: %s\n", phaser.isTerminated());
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/03-07-并发阶段任务中的阶段切换/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.MyPhaser;
4 | import com.concurrency.task.Student;
5 |
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建一个阶段对象
10 | MyPhaser phaser = new MyPhaser();
11 | // 创建一个学生对象,将它们注册到同一个阶段对象中
12 | Student[] students = new Student[5];
13 | for (int i = 0; i < students.length; i++) {
14 | students[i] = new Student(phaser);
15 | phaser.register();
16 | }
17 |
18 | // 创建五个线程来运行五个学生对象,并且启动线程
19 | Thread[] threads = new Thread[5];
20 | for (int i = 0; i < students.length; i++) {
21 | threads[i] = new Thread(students[i]);
22 | threads[i].start();
23 | }
24 |
25 | // 等待所有线程完成执行
26 | try {
27 | for (int i = 0; i < threads.length; i++) {
28 | threads[i].join();
29 | }
30 | } catch (InterruptedException e) {
31 | e.printStackTrace();
32 | }
33 |
34 | // 检查阶段是否已经到达完成状态
35 | System.out.printf("Main: The phaser has finished: %s.\n", phaser.isTerminated());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/03-07-并发阶段任务中的阶段切换/src/com/concurrency/task/MyPhaser.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Phaser;
4 |
5 | /**
6 | * 线程阶段类,控制线程阶段的改变
7 | */
8 | public class MyPhaser extends Phaser {
9 | /**
10 | * @param phase 实际的阶段
11 | * @param registeredParties 注册的线程数
12 | * @return false表明要进一步执行,true表明已经完成
13 | */
14 | @Override
15 | protected boolean onAdvance(int phase, int registeredParties) {
16 | switch (phase) {
17 | case 0:
18 | return studentArrived();
19 | case 1:
20 | return finishFirstExercise();
21 | case 2:
22 | return finishSecondExercise();
23 | case 3:
24 | return finishExam();
25 | default:
26 | return true;
27 | }
28 | }
29 |
30 | /**
31 | * 从0->1阶段改变时调用这个方法
32 | *
33 | * @return 总是返回false,表明还要断续执行
34 | */
35 | private boolean studentArrived() {
36 | System.out.printf("Phaser: The exam are going to start. The students are ready.\n");
37 | System.out.printf("Phaser: We have %d students.\n", getRegisteredParties());
38 | return false;
39 | }
40 |
41 | /**
42 | * 从1->2阶段改变时调用这个方法
43 | *
44 | * @return 总是返回false,表明还要断续执行
45 | */
46 | private boolean finishFirstExercise() {
47 | System.out.printf("Phaser: All the students has finished the first exercise.\n");
48 | System.out.printf("Phaser: It's turn for the second one.\n");
49 | return false;
50 | }
51 |
52 | /**
53 | * 从2->3阶段改变时调用这个方法
54 | *
55 | * @return 总是返回false,表明还要断续执行
56 | */
57 | private boolean finishSecondExercise() {
58 | System.out.printf("Phaser: All the students has finished the second exercise.\n");
59 | System.out.printf("Phaser: It's turn for the third one.\n");
60 | return false;
61 | }
62 |
63 | /**
64 | * 从3->4阶段改变时调用这个方法
65 | *
66 | * @return 总是返回false,表明还要断续执行
67 | */
68 | private boolean finishExam() {
69 | System.out.printf("Phaser: All the students has finished the exam.\n");
70 | System.out.printf("Phaser: Thank you for your time.\n");
71 | return true;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/03-07-并发阶段任务中的阶段切换/src/com/concurrency/task/Student.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.Phaser;
5 | import java.util.concurrent.TimeUnit;
6 |
7 | /**
8 | * 学生类
9 | */
10 | public class Student implements Runnable {
11 | /**
12 | * 控制线程执行的阶段对象
13 | */
14 | private Phaser phaser;
15 |
16 | /**
17 | * 构造函数
18 | * @param phaser 控制线程招手执行的阶段对象
19 | */
20 | public Student(Phaser phaser) {
21 | this.phaser = phaser;
22 | }
23 |
24 | /**
25 | * 核心方法,进入考试状态,做三个测试题,每做完一个测试题,它调用阶段对象等待所有其的学生都完成同样的测试题
26 | */
27 | @Override
28 | public void run() {
29 | System.out.printf("%s: Has arrived to do the exam. %s\n", Thread.currentThread().getName(), new Date());
30 | phaser.arriveAndAwaitAdvance();
31 |
32 | System.out.printf("%s: Is going to do the first exercise. %s\n", Thread.currentThread().getName(), new Date());
33 | doExercise1();
34 | System.out.printf("%s: Has done the first exercise. %s\n", Thread.currentThread().getName(), new Date());
35 | phaser.arriveAndAwaitAdvance();
36 |
37 | System.out.printf("%s: Is going to do the second exercise. %s\n", Thread.currentThread().getName(), new Date());
38 | doExercise2();
39 | System.out.printf("%s: Has done the second exercise. %s\n", Thread.currentThread().getName(), new Date());
40 | phaser.arriveAndAwaitAdvance();
41 |
42 | System.out.printf("%s: Is going to do the third exercise. %s\n", Thread.currentThread().getName(), new Date());
43 | doExercise3();
44 | System.out.printf("%s: Has finished the exam. %s\n", Thread.currentThread().getName(), new Date());
45 | phaser.arriveAndAwaitAdvance();
46 | }
47 |
48 | /**
49 | * 做一个测试题,并且休眠[0, 10)秒
50 | */
51 | private void doExercise1() {
52 | try {
53 | Long duration = (long) (Math.random() * 10);
54 | TimeUnit.SECONDS.sleep(duration);
55 | } catch (InterruptedException e) {
56 | e.printStackTrace();
57 | }
58 | }
59 |
60 | /**
61 | * 做一个测试题,并且休眠[0, 10)秒
62 | */
63 | private void doExercise2() {
64 | try {
65 | Long duration = (long) (Math.random() * 10);
66 | TimeUnit.SECONDS.sleep(duration);
67 | } catch (InterruptedException e) {
68 | e.printStackTrace();
69 | }
70 | }
71 |
72 | /**
73 | * 做一个测试题,并且休眠[0, 10)秒
74 | */
75 | private void doExercise3() {
76 | try {
77 | Long duration = (long) (Math.random() * 10);
78 | TimeUnit.SECONDS.sleep(duration);
79 | } catch (InterruptedException e) {
80 | e.printStackTrace();
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/03-08-并发任务间的数据交换/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Consumer;
4 | import com.concurrency.task.Producer;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.concurrent.Exchanger;
9 |
10 | public class Main {
11 | public static void main(String[] args) {
12 | // 创建两个缓存对象
13 | List buffer1 = new ArrayList<>();
14 | List buffer2 = new ArrayList<>();
15 |
16 | // 创建一个交换器对象
17 | Exchanger> exchanger = new Exchanger<>();
18 |
19 | // 创建生产者对象
20 | Producer producer = new Producer(exchanger, buffer1);
21 | // 创建消费者对象
22 | Consumer consumer = new Consumer(exchanger, buffer2);
23 |
24 | // 创建消费者对象和生产者对象放置在不同的线程中
25 | Thread threadProducer = new Thread(producer);
26 | Thread threadConsumer = new Thread(consumer);
27 |
28 | // 启动两个线程
29 | threadProducer.start();
30 | threadConsumer.start();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/03-08-并发任务间的数据交换/src/com/concurrency/task/Consumer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.List;
4 | import java.util.concurrent.Exchanger;
5 |
6 | /**
7 | * 消费者类
8 | */
9 | public class Consumer implements Runnable {
10 |
11 | /**
12 | * 消费者消费数据的地方,也是与消费者交换数据的地方
13 | */
14 | private List buffer;
15 | /**
16 | * 同步生产者与消息者交换数据的交换对象
17 | */
18 | private final Exchanger> exchanger;
19 |
20 | /**
21 | * 构造函数,初始化属性
22 | *
23 | * @param exchanger 数据的交换对象
24 | * @param buffer 数据存储对象
25 | */
26 | public Consumer(Exchanger> exchanger, List buffer) {
27 | this.exchanger = exchanger;
28 | this.buffer = buffer;
29 | }
30 |
31 | /**
32 | * 核心方法,它消费生产者产生的事件,每消费10个事件后,它使用交换对象去同步生产者。
33 | * 它将已经消费完的空缓存对象发送给生产者,同时获取生产者生产的装有10个事件的缓存对象
34 | */
35 | @Override
36 | public void run() {
37 | int cycle = 1;
38 | for (int i = 0; i < 10; i++) {
39 | System.out.printf("Consumer: Cycle %d\n", cycle);
40 |
41 | try {
42 | // 等待生产的数据,并且将空的缓存对象发送给生产者
43 | buffer = exchanger.exchange(buffer);
44 | } catch (InterruptedException e) {
45 | e.printStackTrace();
46 | }
47 |
48 | System.out.printf("Consumer: %d\n", buffer.size());
49 |
50 | for (int j = 0; j < 10; j++) {
51 | String message = buffer.get(0);
52 | System.out.printf("Consumer: %s\n", message);
53 | buffer.remove(0);
54 | }
55 |
56 | cycle++;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/03-08-并发任务间的数据交换/src/com/concurrency/task/Producer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.List;
4 | import java.util.concurrent.Exchanger;
5 |
6 | /**
7 | * 生产者类
8 | */
9 | public class Producer implements Runnable {
10 | /**
11 | * 生产者生产数据后存储的地方,也是与消费者交换数据的地方
12 | */
13 | private List buffer;
14 | /**
15 | * 同步生产者与消息者交换数据的交换对象
16 | */
17 | private final Exchanger> exchanger;
18 |
19 | /**
20 | * 构造函数,初始化属性
21 | *
22 | * @param exchanger 数据的交换对象
23 | * @param buffer 数据存储对象
24 | */
25 | public Producer(Exchanger> exchanger, List buffer) {
26 | this.exchanger = exchanger;
27 | this.buffer = buffer;
28 | }
29 |
30 | /**
31 | * 核心方法,产生100个事件,分10次产生,每次产生10个事件,每个产生10个事件后,
32 | * 调用数据交换对象去同步消费者。生产者将存放10个事件的缓存对象发送给消费者,
33 | * 并且从消费者那里接收到一个空的缓存对象
34 | */
35 | @Override
36 | public void run() {
37 | int cycle = 1;
38 | for (int i = 0; i < 10; i++) {
39 | System.out.printf("Producer: Cycle %d\n", cycle);
40 | // 生产10个事件
41 | for (int j = 0; j < 10; j++) {
42 | String message = "Event " + ((i * 10) + j);
43 | System.out.printf("Producer: %s\n", message);
44 | buffer.add(message);
45 | }
46 |
47 | try {
48 | // 与消费者交换数据
49 | buffer = exchanger.exchange(buffer);
50 | } catch (InterruptedException e) {
51 | e.printStackTrace();
52 | }
53 |
54 | System.out.printf("Producer: %d\n", buffer.size());
55 |
56 | cycle++;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/04-02-创建线程执行器/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Server;
4 | import com.concurrency.task.Task;
5 |
6 | public class Main {
7 | public static void main(String[] args) {
8 | Server server = new Server();
9 |
10 | // 发送100个任务到服务器对象,并且完成任务
11 | for (int i = 0; i < 100; i++) {
12 | Task task = new Task("Task " + i);
13 | server.executeTask(task);
14 | }
15 |
16 | server.endServer();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/04-02-创建线程执行器/src/com/concurrency/task/Server.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Executors;
4 | import java.util.concurrent.ThreadPoolExecutor;
5 |
6 | /**
7 | * 服务类,模拟一个服务器
8 | */
9 | public class Server {
10 | /**
11 | * 线程池执行器,管理请求线程的执行
12 | */
13 | private ThreadPoolExecutor executor;
14 |
15 | /**
16 | * 构造函数,创建线程执行器对象
17 | */
18 | public Server() {
19 | executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); // 本质是一个缓冲线程池对象
20 | }
21 |
22 | /**
23 | * 任务执行方法 接收Task对象作为参数并将其提交到执行者
24 | *
25 | * @param task Task对象
26 | */
27 | public void executeTask(Task task) {
28 | // 首先,写入一条信息到控制台,表明有一个新的任务到达。
29 | System.out.printf("Server: A new task has arrived\n");
30 | // 然后,调用执行者的execute()方法来提交这个任务
31 | executor.execute(task);
32 | // 最后,将执行者的数据写入到控制台来看它们的状态
33 | System.out.printf("Server: Pool Size: %d\n", executor.getPoolSize());
34 | System.out.printf("Server: Active Count: %d\n", executor.getActiveCount());
35 | System.out.printf("Server: Completed Tasks: %d\n", executor.getCompletedTaskCount());
36 | }
37 |
38 | /**
39 | * 结束执行的方法
40 | */
41 | public void endServer() {
42 | // 调用执行者的shutdown()方法来结束任务执行
43 | executor.shutdown();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/04-02-创建线程执行器/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 任务类
8 | */
9 | public class Task implements Runnable {
10 | /**
11 | * 任务创建的时间
12 | */
13 | private Date initDate;
14 | /**
15 | * 任务的名称
16 | */
17 | private String name;
18 |
19 | /**
20 | * 构造函数,初始化属性
21 | *
22 | * @param name 任务的名称
23 | */
24 | public Task(String name) {
25 | this.initDate = new Date();
26 | this.name = name;
27 | }
28 |
29 | /**
30 | * 核心类,执行任务,等待一个随机的时间完成任务
31 | */
32 | @Override
33 | public void run() {
34 | System.out.printf("%s: Task %s: Created on: %s\n", Thread.currentThread().getName(), name, initDate);
35 | System.out.printf("%s: Task %s: Started on: %s\n", Thread.currentThread().getName(), name, new Date());
36 |
37 | try {
38 | Long duration = (long) (Math.random() * 10);
39 | System.out.printf("%s: Task %s: Doing a task during %d seconds\n", Thread.currentThread().getName(), name, duration);
40 | TimeUnit.SECONDS.sleep(duration);
41 | } catch (InterruptedException e) {
42 | e.printStackTrace();
43 | }
44 |
45 | System.out.printf("%s: Task %s: Finished on: %s\n", Thread.currentThread().getName(), name, new Date());
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/04-03-创建固定大小的线程执行器/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Server;
4 | import com.concurrency.task.Task;
5 |
6 | public class Main {
7 | public static void main(String[] args) {
8 | Server server = new Server();
9 |
10 | // 发送100个任务到服务器对象,并且完成任务
11 | for (int i = 0; i < 100; i++) {
12 | Task task = new Task("Task " + i);
13 | server.executeTask(task);
14 | }
15 |
16 | server.endServer();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/04-03-创建固定大小的线程执行器/src/com/concurrency/task/Server.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Executors;
4 | import java.util.concurrent.ThreadPoolExecutor;
5 |
6 | /**
7 | * 服务类,模拟一个服务器
8 | */
9 | public class Server {
10 | /**
11 | * 线程池执行器,管理请求线程的执行
12 | */
13 | private ThreadPoolExecutor executor;
14 |
15 | /**
16 | * 构造函数,创建线程执行器对象
17 | */
18 | public Server() {
19 | executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5); // 本质是一个固定大小的线程池对象
20 | }
21 |
22 | /**
23 | * 任务执行方法 接收Task对象作为参数并将其提交到执行者
24 | *
25 | * @param task Task对象
26 | */
27 | public void executeTask(Task task) {
28 | // 首先,写入一条信息到控制台,表明有一个新的任务到达。
29 | System.out.printf("Server: A new task has arrived\n");
30 | // 然后,调用执行者的execute()方法来提交这个任务
31 | executor.execute(task);
32 | // 最后,将执行者的数据写入到控制台来看它们的状态
33 | System.out.printf("Server: Pool Size: %d\n", executor.getPoolSize());
34 | System.out.printf("Server: Active Count: %d\n", executor.getActiveCount());
35 | System.out.printf("Server: Task Count: %d\n",executor.getTaskCount());
36 | System.out.printf("Server: Completed Tasks: %d\n",executor.getCompletedTaskCount());
37 | }
38 |
39 | /**
40 | * 结束执行的方法
41 | */
42 | public void endServer() {
43 | // 调用执行者的shutdown()方法来结束任务执行
44 | executor.shutdown();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/04-03-创建固定大小的线程执行器/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 任务类
8 | */
9 | public class Task implements Runnable {
10 | /**
11 | * 任务创建的时间
12 | */
13 | private Date initDate;
14 | /**
15 | * 任务的名称
16 | */
17 | private String name;
18 |
19 | /**
20 | * 构造函数,初始化属性
21 | *
22 | * @param name 任务的名称
23 | */
24 | public Task(String name) {
25 | this.initDate = new Date();
26 | this.name = name;
27 | }
28 |
29 | /**
30 | * 核心类,执行任务,等待一个随机的时间完成任务
31 | */
32 | @Override
33 | public void run() {
34 | System.out.printf("%s: Task %s: Created on: %s\n", Thread.currentThread().getName(), name, initDate);
35 | System.out.printf("%s: Task %s: Started on: %s\n", Thread.currentThread().getName(), name, new Date());
36 |
37 | try {
38 | Long duration = (long) (Math.random() * 10);
39 | System.out.printf("%s: Task %s: Doing a task during %d seconds\n", Thread.currentThread().getName(), name, duration);
40 | TimeUnit.SECONDS.sleep(duration);
41 | } catch (InterruptedException e) {
42 | e.printStackTrace();
43 | }
44 |
45 | System.out.printf("%s: Task %s: Finished on: %s\n", Thread.currentThread().getName(), name, new Date());
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/04-04-在执行器中执行任务并返回结果/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.FactorialCalculator;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import java.util.Random;
8 | import java.util.concurrent.ExecutionException;
9 | import java.util.concurrent.Executors;
10 | import java.util.concurrent.Future;
11 | import java.util.concurrent.ThreadPoolExecutor;
12 |
13 | public class Main {
14 | public static void main(String[] args) {
15 | // 创建固定大小的线程池执行器,最多可以同时执行2个线程。
16 | ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
17 | // 创建一个存储未来象的列表,未来对象关联着任务的任务的执行,并且可以获取执行的结果
18 | List> resultList = new ArrayList<>();
19 | // 创建一个随机数生成对象
20 | Random random = new Random();
21 |
22 | // 创建10个任务并且将它们送到执行器中
23 | for (int i = 0; i < 10; i++) {
24 | // 生成[0, 10)之间的10个随机数
25 | Integer number = random.nextInt(10);
26 | FactorialCalculator calculator = new FactorialCalculator(number);
27 | // 调用执行器的submit()方法来提交FactorialCalculator任务给执行者。
28 | // 这个方法返回Future对象来管理任务,并且最终获取它的结果。
29 | Future result = executor.submit(calculator);
30 | // 将结果存储到队列当中
31 | resultList.add(result);
32 | }
33 | // 创建一个do循环来监控执行者的状态,等待10个线程都完成任务。
34 | do {
35 | // 首先,写入信息到控制台,使用执行器的getCompletedTaskNumber()方法获得的已完成的任务数。
36 | System.out.printf("Main: Number of Completed Tasks: %d\n", executor.getCompletedTaskCount());
37 | // 然后,对于队列中的10个Future对象,使用isDone()方法,将信息写入(到控制台)表明它们所管理的任务是否已经完成
38 | for (int i = 0; i < resultList.size(); i++) {
39 | Future result = resultList.get(i);
40 | System.out.printf("Main: Task %d: %s\n", i, result.isDone());
41 | }
42 |
43 | try {
44 | // 主线程休眠50毫秒
45 | Thread.sleep(50);
46 | } catch (InterruptedException e) {
47 | e.printStackTrace();
48 | }
49 | // 如果执行器中的已完成任务数小于10,重复这个循环。
50 | } while (executor.getCompletedTaskCount() < resultList.size());
51 |
52 | // 将获得的每个任务的结果写入控制台。对于每个Future对象,通过它的任务使用get()方法获取返回的Integer对象。
53 | System.out.printf("Main: Results\n");
54 | for (int i = 0; i < resultList.size(); i++) {
55 | Future result = resultList.get(i);
56 | Integer number = null;
57 | try {
58 | number = result.get();
59 | } catch (InterruptedException e) {
60 | e.printStackTrace();
61 | } catch (ExecutionException e) {
62 | e.printStackTrace();
63 | }
64 | // 在控制台输出结果
65 | System.out.printf("Core: Task %d: %d\n", i, number);
66 | }
67 |
68 | // 最后,调用执行器的shutdown()方法来结束这个执行器。
69 | executor.shutdown();
70 |
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/04-04-在执行器中执行任务并返回结果/src/com/concurrency/task/FactorialCalculator.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Callable;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 阶乘计算类,实现Callable接口,并参数化为Integer类型
8 | */
9 | public class FactorialCalculator implements Callable {
10 | /**
11 | * 声明一个私有的,类型为Integer,名为number的属性,用来存储任务将要计算的数
12 | */
13 | private Integer number;
14 |
15 | /**
16 | * 构造函数,初始化
17 | * @param number 将要计算的数
18 | */
19 | public FactorialCalculator(Integer number) {
20 | this.number = number;
21 | }
22 |
23 | /**
24 | * 核心方法,返回阶乘计算的结果
25 | * @return 阶乘计算的结果
26 | * @throws Exception
27 | */
28 | @Override
29 | public Integer call() throws Exception {
30 | int num, result;
31 | num = number;
32 | result = 1;
33 |
34 | // 如果数是1或0,则返回1。否则,计算这个数的阶乘。为了演示效果,在两次乘之间,令这个任务睡眠20毫秒。
35 | if (num == 0 || num == 1) {
36 | return 1;
37 | } else {
38 | for (int i = 2; i <= number; i++) {
39 | result *= i;
40 | TimeUnit.MICROSECONDS.sleep(20);
41 | }
42 |
43 | }
44 | // 操作结果的信息写入控制台。
45 | System.out.printf("%s: %d\n", Thread.currentThread().getName(), result);
46 | // 返回操作结果。
47 | return result;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/04-05-运行多个任务并处理第一个结果/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.TaskValidator;
4 | import com.concurrency.task.UserValidator;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.concurrent.ExecutionException;
9 | import java.util.concurrent.ExecutorService;
10 | import java.util.concurrent.Executors;
11 |
12 | public class Main {
13 | public static void main(String[] args) {
14 | // 创建两个String对象,一个名为name,另一个名为password,使用”test”值初始化它们。
15 | String username = "test";
16 | String password = "test";
17 |
18 | // 创建两个UserValidator对象,一个名为ldapValidator,另一个名为dbValidator。
19 | UserValidator ldapValidator = new UserValidator("LDAP");
20 | UserValidator dbValidator = new UserValidator("DataBase");
21 |
22 | // 创建两个TaskValidator对象,分别为ldapTask和dbTask。分别使用ldapValidator和dbValidator初始化它们。
23 | TaskValidator ldapTask = new TaskValidator(ldapValidator, username, password);
24 | TaskValidator dbTask = new TaskValidator(dbValidator, username, password);
25 |
26 | // 创建TaskValidator队列,添加两个已创建的对象(ldapTask和dbTask)
27 | List taskList = new ArrayList<>();
28 | taskList.add(ldapTask);
29 | taskList.add(dbTask);
30 |
31 | // 使用Executors类的newCachedThreadPool()方法创建一个新的ThreadPoolExecutor对象和一个类型为String,
32 | // 名为result的变量。
33 | ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool();
34 | String result;
35 | try {
36 | // 调用executor对象的invokeAny()方法。该方法接收taskList参数,返回String类型。
37 | // 同样,它将该方法返回的String对象写入到控制台。
38 | result = executor.invokeAny(taskList);
39 | System.out.printf("Main: Result: %s\n", result);
40 | } catch (InterruptedException e) {
41 | e.printStackTrace();
42 | } catch (ExecutionException e) {
43 | e.printStackTrace();
44 | }
45 |
46 | // 使用shutdown()方法结束执行者,写入一条信息到控制台,表明程序已结束。
47 | executor.shutdown();
48 | System.out.printf("Main: End of the Execution\n");
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/04-05-运行多个任务并处理第一个结果/src/com/concurrency/task/TaskValidator.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Callable;
4 |
5 | /**
6 | * 任务验证类,用来执行UserValidation对象作为并发任务的验证过程。指定它实现Callable接口,并参数化为String类型。
7 | */
8 | public class TaskValidator implements Callable {
9 | /**
10 | * 声明一个私有的、类型为UserValidator、名为validator的属性。
11 | */
12 | private UserValidator validator;
13 | /**
14 | * 声明私有的、类型为String、名为user的属性。
15 | */
16 | private String user;
17 | /**
18 | * 声明私有的、类型为String、名为password的属性。
19 | */
20 | private String password;
21 |
22 | /**
23 | * 构造函数,初始化属性
24 | *
25 | * @param validator 用户验证对象
26 | * @param user 用户名
27 | * @param password 用户密码
28 | */
29 | public TaskValidator(UserValidator validator, String user, String password) {
30 | this.validator = validator;
31 | this.user = user;
32 | this.password = password;
33 | }
34 |
35 | /**
36 | * 核心方法,使用用户验证对象进行用户名和密码验证,如果验证通过就返回验证的名字,否则就抛出异常
37 | *
38 | * @return 验证的名字
39 | * @throws Exception 验证不通过就抛出异常
40 | */
41 | @Override
42 | public String call() throws Exception {
43 | // 如果用户没有通过UserValidator对象验证,写入一条信息到控制台,表明这种情况,并且抛出一个Exception异常
44 | if (!validator.validate(user, password)) {
45 | System.out.printf("%s: The user has not been found\n", validator.getName());
46 | throw new Exception("Error validating user");
47 | }
48 |
49 | // 否则,写入一条信息到控制台表明用户已通过验证,并返回UserValidator对象的名称。
50 | System.out.printf("%s: The user has been found\n", validator.getName());
51 | return validator.getName();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/04-05-运行多个任务并处理第一个结果/src/com/concurrency/task/UserValidator.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Random;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 用户检验类,实现用户验证过程
8 | */
9 | public class UserValidator {
10 | /**
11 | * 声明一个私有的、类型为String、名为name的属性,用来存储系统验证用户的名称。
12 | */
13 | private String name;
14 |
15 | /**
16 | * 构造函数,初始化用户名称
17 | *
18 | * @param name 用户名称
19 | */
20 | public UserValidator(String name) {
21 | this.name = name;
22 | }
23 |
24 | /**
25 | * 验证方法,根据用户名和密码进行验
26 | *
27 | * @param name 用户名
28 | * @param password 密码
29 | * @return true验证通过,false验证失败
30 | */
31 | public boolean validate(String name, String password) {
32 | // 创建Random对象,名为random。
33 | Random random = new Random();
34 |
35 | // 等待一个随机时间,用来模拟用户验证的过程
36 | try {
37 | Long duration = (long) (Math.random() * 10);
38 | System.out.printf("Validator %s: Validating a user during %d seconds\n", this.name, duration);
39 | TimeUnit.SECONDS.sleep(duration);
40 | } catch (InterruptedException e) {
41 | return false;
42 | }
43 |
44 | // 返回一个随机Boolean值。如果用户验证通过,这个方法将返回true,否则,返回false。
45 | return random.nextBoolean();
46 | }
47 |
48 | /**
49 | * 返回name属性值
50 | *
51 | * @return name属性值
52 | */
53 | public String getName() {
54 | return name;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/04-06-运行多个任务并且处理所有结果/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Result;
4 | import com.concurrency.task.Task;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.concurrent.*;
9 |
10 | public class Main {
11 | public static void main(String[] args) {
12 | // 使用Executors类的newCachedThreadPool()方法,创建ThreadPoolExecutor对象。
13 | ExecutorService executor = Executors.newCachedThreadPool();
14 |
15 | // 创建三个Task对象,并且将他们存储在一个链表当中
16 | List taskList = new ArrayList<>();
17 | for (int i = 0; i < 3; i++) {
18 | Task task = new Task("Task-" + i);
19 | taskList.add(task);
20 | }
21 |
22 | // 创建Future对象列表,参数化为Result类型。
23 | List> resultList = null;
24 | try {
25 | // 调用ThreadPoolExecutor类的invokeAll()方法。这个类将会返回之前创建的Future对象列表。
26 | resultList = executor.invokeAll(taskList);
27 | } catch (InterruptedException e) {
28 | e.printStackTrace();
29 | }
30 |
31 | // 使用shutdown()方法结束执行器的执行。
32 | executor.shutdown();
33 |
34 | // 将结果写入控制台
35 | System.out.printf("Core: Printing the results\n");
36 | for (Future future : resultList) {
37 | try {
38 | Result result = future.get();
39 | System.out.printf("%s: %s\n", result.getName(), result.getValue());
40 | } catch (InterruptedException | ExecutionException e) {
41 | e.printStackTrace();
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/04-06-运行多个任务并且处理所有结果/src/com/concurrency/task/Result.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 结果类,存储中并发任务产生的结果
5 | */
6 | public class Result {
7 | /**
8 | * 产生结果的任务的名字
9 | */
10 | private String name;
11 | /**
12 | * 产生的结果值
13 | */
14 | private int value;
15 |
16 | /**
17 | * 返回任务的名字
18 | *
19 | * @return 任务的名字
20 | */
21 | public String getName() {
22 | return name;
23 | }
24 |
25 | /**
26 | * 设备任务的名字
27 | *
28 | * @param name 任务的名字
29 | */
30 | public void setName(String name) {
31 | this.name = name;
32 | }
33 |
34 | /**
35 | * 返回结果
36 | *
37 | * @return 结果值
38 | */
39 | public int getValue() {
40 | return value;
41 | }
42 |
43 | /**
44 | * 设置结果
45 | *
46 | * @param value 结果值
47 | */
48 | public void setValue(int value) {
49 | this.value = value;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/04-06-运行多个任务并且处理所有结果/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Callable;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 任务类,实现Callable接口,参数化为Result类型。
8 | */
9 | public class Task implements Callable {
10 | /**
11 | * 任务的名称
12 | */
13 | private String name;
14 |
15 | /**
16 | * 构造函数
17 | *
18 | * @param name 初始化任务的名称
19 | */
20 | public Task(String name) {
21 | this.name = name;
22 | }
23 |
24 | /**
25 | * 核心方法,等待一个随机时间,并且计算5个随机数的和
26 | *
27 | * @return 个随机数的和
28 | * @throws Exception
29 | */
30 | @Override
31 | public Result call() throws Exception {
32 | // 向控制台输出信息
33 | System.out.printf("%s: Staring\n", this.name);
34 |
35 | // 等待一个随机的时间
36 | try {
37 | Long duration = (long) (Math.random() * 10);
38 | System.out.printf("%s: Waiting %d seconds for results.\n", this.name, duration);
39 | TimeUnit.SECONDS.sleep(duration);
40 | } catch (InterruptedException e) {
41 | e.printStackTrace();
42 | }
43 |
44 | // 计算随机数的和
45 | int value = 0;
46 | for (int i = 0; i < 5; i++) {
47 | value += (int) (Math.random() * 100);
48 |
49 | }
50 |
51 | // 创建一个结果对象
52 | Result result = new Result();
53 | result.setName(this.name);
54 | result.setValue(value);
55 | System.out.printf("%s: Ends\n", this.name);
56 |
57 | // 返回结果对象
58 | return result;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/04-07-在执行器中延时执行任务/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Task;
4 |
5 | import java.util.Date;
6 | import java.util.concurrent.Executors;
7 | import java.util.concurrent.ScheduledExecutorService;
8 | import java.util.concurrent.ScheduledThreadPoolExecutor;
9 | import java.util.concurrent.TimeUnit;
10 |
11 | public class Main {
12 | public static void main(String[] args) {
13 | // 创建一个定时线程池执行器对象
14 | ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
15 |
16 | // 使用ScheduledThreadPoolExecutor实例的schedule()方法,初始化和开始一些任务(5个任务)。
17 | System.out.printf("Main: Starting at: %s\n", new Date());
18 | for (int i = 0; i < 5; i++) {
19 | Task task = new Task("Task " + i);
20 | executor.schedule(task, i + 1, TimeUnit.SECONDS);
21 | }
22 |
23 | // 关闭线程执行器对象
24 | executor.shutdown();
25 |
26 | // 等待线程执行器的完成
27 | try {
28 | // 所有线程必须在24小时内完成,否则就终止未完成的线程
29 | executor.awaitTermination(1, TimeUnit.DAYS);
30 | } catch (InterruptedException e) {
31 | e.printStackTrace();
32 | }
33 |
34 | // 输出完成消息
35 | System.out.printf("Core: Ends at: %s\n", new Date());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/04-07-在执行器中延时执行任务/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.Callable;
5 |
6 | /**
7 | * 任务类,实现Callable接口,参数化为String类型。
8 | */
9 | public class Task implements Callable {
10 | /**
11 | * 任务名称
12 | */
13 | private String name;
14 |
15 | /**
16 | * 构造函数,初始化任务名称
17 | *
18 | * @param name 任务名称
19 | */
20 | public Task(String name) {
21 | this.name = name;
22 | }
23 |
24 | /**
25 | * 核心方法,输出任务执行时间
26 | *
27 | * @return 执行结果字符串
28 | * @throws Exception
29 | */
30 | @Override
31 | public String call() throws Exception {
32 | System.out.printf("%s: Starting at : %s\n", name, new Date());
33 | return "Hello, world";
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/04-08-在执行器中周期性执行任务/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Task;
4 |
5 | import java.util.Date;
6 | import java.util.concurrent.*;
7 |
8 | public class Main {
9 | public static void main(String[] args) {
10 | // 创建一个定时行器服务对象
11 | ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
12 | System.out.printf("Main: Starting at: %s\n", new Date());
13 |
14 | // 创建一个执行任务,并且将它放入执行器中,初始延迟是1秒,周期是2秒
15 | Task task = new Task("Task");
16 | ScheduledFuture> result = executor.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS);
17 |
18 | // 控制任务的执行
19 | for (int i = 0; i < 10; i++) {
20 | System.out.printf("Main: Delay: %d\n", result.getDelay(TimeUnit.MILLISECONDS));
21 | try {
22 | TimeUnit.MILLISECONDS.sleep(500);
23 | } catch (InterruptedException e) {
24 | e.printStackTrace();
25 | }
26 | }
27 |
28 | // 关闭执行器对象
29 | executor.shutdown();
30 | System.out.printf("Main: No more tasks at: %s\n", new Date());
31 |
32 | // 验证在执行器关闭后,周期性任务不会执行
33 | try {
34 | TimeUnit.SECONDS.sleep(5);
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }
38 | // 输出完成信息
39 | System.out.printf("Main: Finished at: %s\n", new Date());
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/04-08-在执行器中周期性执行任务/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * 任务类,执行任务
7 | */
8 | public class Task implements Runnable {
9 | /**
10 | * 任务的名称
11 | */
12 | private String name;
13 |
14 | /**
15 | * 构造函数,初始化任务名称
16 | *
17 | * @param name 任务名称
18 | */
19 | public Task(String name) {
20 | this.name = name;
21 | }
22 |
23 | /**
24 | * 核心方法,向控制台输出当前执行的时间
25 | */
26 | @Override
27 | public void run() {
28 | System.out.printf("%s: Executed at: %s\n",name,new Date());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/04-09-在执行器中取消任务/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Task;
4 |
5 | import java.util.concurrent.Executors;
6 | import java.util.concurrent.Future;
7 | import java.util.concurrent.ThreadPoolExecutor;
8 | import java.util.concurrent.TimeUnit;
9 |
10 | public class Main {
11 | public static void main(String[] args) {
12 | // 创建一个执行器
13 | ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
14 |
15 | // 创建一个任务
16 | Task task = new Task();
17 |
18 | System.out.printf("Main: Executing the Task\n");
19 |
20 | // 把任务发送到执行器
21 | Future result = executor.submit(task);
22 |
23 | // 休眠两秒钟
24 | try {
25 | TimeUnit.SECONDS.sleep(2);
26 | } catch (InterruptedException e) {
27 | e.printStackTrace();
28 | }
29 |
30 | // 取消一个任务完成他的执行
31 | System.out.printf("Main: Cancelling the Task\n");
32 | result.cancel(true);
33 |
34 | // 验证任务是否被取消
35 | System.out.printf("Main: Cancelled: %s\n", result.isCancelled());
36 | System.out.printf("Main: Done: %s\n", result.isDone());
37 |
38 | // 关闭执行器
39 | executor.shutdown();
40 | System.out.printf("Main: The executor has finished\n");
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/04-09-在执行器中取消任务/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Callable;
4 |
5 | public class Task implements Callable {
6 | /**
7 | * 核心方法,一个无限循环的任务,每100毫秒向控制台写一个消息
8 | * @return
9 | * @throws Exception
10 | */
11 | @Override
12 | public String call() throws Exception {
13 | while (true){
14 | System.out.printf("Task: Test\n");
15 | Thread.sleep(100);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/04-10-在执行器中控制任务的完成/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.ExecutableTask;
4 | import com.concurrency.task.ResultTask;
5 |
6 | import java.util.concurrent.ExecutionException;
7 | import java.util.concurrent.ExecutorService;
8 | import java.util.concurrent.Executors;
9 | import java.util.concurrent.TimeUnit;
10 |
11 | public class Main {
12 | public static void main(String[] args) {
13 | // 创建一个执行器对象
14 | ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool();
15 |
16 | // 创建5个任务
17 | ResultTask resultTasks[] = new ResultTask[5];
18 | for (int i = 0; i < 5; i++) {
19 | ExecutableTask executableTask = new ExecutableTask("Task " + i);
20 | resultTasks[i] = new ResultTask(executableTask);
21 | executor.submit(resultTasks[i]);
22 | }
23 |
24 | // 休眠5秒钟
25 | try {
26 | TimeUnit.SECONDS.sleep(5);
27 | } catch (InterruptedException e1) {
28 | e1.printStackTrace();
29 | }
30 |
31 | // 取消所有的任务,如果任务在取消之前已经完,取消操作对任务没有任命影响
32 | for (ResultTask resultTask : resultTasks) {
33 | resultTask.cancel(true);
34 | }
35 |
36 | // 输出未被取消的任务的结果
37 | for (ResultTask resultTask : resultTasks) {
38 | try {
39 | if (!resultTask.isCancelled()) {
40 | System.out.printf("%s\n", resultTask.get());
41 | }
42 | } catch (InterruptedException | ExecutionException e) {
43 | e.printStackTrace();
44 | }
45 | }
46 |
47 | // 关闭执行器
48 | executor.shutdown();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/04-10-在执行器中控制任务的完成/src/com/concurrency/task/ExecutableTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Callable;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 任务执行类,并指定其实现Callable接口,参数化为String类型。
8 | */
9 | public class ExecutableTask implements Callable {
10 | /**
11 | * 任务名称
12 | */
13 | private String name;
14 |
15 | public ExecutableTask(String name) {
16 | this.name = name;
17 | }
18 |
19 | /**
20 | * 核心方法,等待一个随机时间,返回一个结果
21 | *
22 | * @return 字符串结果
23 | * @throws Exception
24 | */
25 | @Override
26 | public String call() throws Exception {
27 | try {
28 | Long duration = (long) (Math.random() * 10);
29 | System.out.printf("%s: Waiting %d seconds for results.\n", this.name, duration);
30 | TimeUnit.SECONDS.sleep(duration);
31 | } catch (InterruptedException e) {
32 | //e.printStackTrace();
33 | }
34 | return "Hello, world. I'm " + name;
35 | }
36 |
37 | /**
38 | * 获取任务名称
39 | *
40 | * @return 任务名称
41 | */
42 | public String getName() {
43 | return name;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/04-10-在执行器中控制任务的完成/src/com/concurrency/task/ResultTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Callable;
4 | import java.util.concurrent.FutureTask;
5 |
6 | /**
7 | * 结果任务类,这个类管理着可执行任务类的执行
8 | */
9 | public class ResultTask extends FutureTask {
10 | /**
11 | * 结果任务的名称
12 | */
13 | private String name;
14 |
15 | /**
16 | * 构造函数
17 | *
18 | * @param callable 可调用的接口对象
19 | */
20 | public ResultTask(Callable callable) {
21 | super(callable);
22 | this.name = ((ExecutableTask) callable).getName();
23 | }
24 |
25 | /**
26 | * 当任务完成时调用这个方法
27 | */
28 | @Override
29 | protected void done() {
30 | if (isCancelled()) {
31 | System.out.printf("%s: Has been cancelled\n", name);
32 | } else {
33 | System.out.printf("%s: Has finished\n", name);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.ReportProcessor;
4 | import com.concurrency.task.ReportRequest;
5 |
6 | import java.util.concurrent.*;
7 |
8 | public class Main {
9 | public static void main(String[] args) {
10 | // 创建一个执行器对象和三个完成服务对象,执行器对象供完成服务对象使用
11 | ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool();
12 | CompletionService service = new ExecutorCompletionService<>(executor);
13 |
14 | // 创建两报表请求对象和两个线程来执行他们
15 | ReportRequest faceRequest = new ReportRequest("Face", service);
16 | ReportRequest onlineRequest = new ReportRequest("Online", service);
17 | Thread faceThread = new Thread(faceRequest);
18 | Thread onlineThread = new Thread(onlineRequest);
19 |
20 | // 创建一个报表处理对象和一个执行它的线程
21 | ReportProcessor processor = new ReportProcessor(service);
22 | Thread senderThread = new Thread(processor);
23 |
24 | // 启动线程
25 | System.out.printf("Main: Starting the Threads\n");
26 | faceThread.start();
27 | onlineThread.start();
28 | senderThread.start();
29 |
30 | // 等待报表生成器对象的任务完成
31 | try {
32 | System.out.printf("Main: Waiting for the report generators.\n");
33 | faceThread.join();
34 | onlineThread.join();
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }
38 |
39 | // 关闭执行器
40 | System.out.printf("Main: Shuting down the executor.\n");
41 | executor.shutdown();
42 | try {
43 | executor.awaitTermination(1, TimeUnit.DAYS);
44 | } catch (InterruptedException e) {
45 | e.printStackTrace();
46 | }
47 |
48 | // 等待报表发送器对象执行结束
49 | processor.setEnd(true);
50 | System.out.printf("Main: Ends\n");
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/task/ReportGenerator.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.Callable;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 报告生成类,模拟生成报告。
8 | */
9 | public class ReportGenerator implements Callable {
10 | /**
11 | * 报告发送者
12 | */
13 | private String sender;
14 | /**
15 | * 报告的标题
16 | */
17 | private String title;
18 |
19 | /**
20 | * 构造函数,初始化报告发送者,报告的标题
21 | *
22 | * @param sender 报告发送者
23 | * @param title 报告的标题
24 | */
25 | public ReportGenerator(String sender, String title) {
26 | this.sender = sender;
27 | this.title = title;
28 | }
29 |
30 | /**
31 | * 核心方法,等待一个随机时间,产生一个字符串类型的报告
32 | *
33 | * @return 字符串类型的报告
34 | * @throws Exception
35 | */
36 | @Override
37 | public String call() throws Exception {
38 | try {
39 | Long duration = (long) (Math.random() * 10);
40 | System.out.printf("%s_%s: ReportGenerator: Generating a report during %d seconds\n", this.sender, this.title, duration);
41 | TimeUnit.SECONDS.sleep(duration);
42 | } catch (InterruptedException e) {
43 | e.printStackTrace();
44 | }
45 | String ret = sender + ": " + title;
46 | return ret;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/task/ReportProcessor.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.CompletionService;
4 | import java.util.concurrent.ExecutionException;
5 | import java.util.concurrent.Future;
6 | import java.util.concurrent.TimeUnit;
7 |
8 | /**
9 | * 报表处理器类,通过CompletionService对象处理报表生成器的结果
10 | */
11 | public class ReportProcessor implements Runnable {
12 | /**
13 | * 完成服务对象
14 | */
15 | private CompletionService service;
16 | /**
17 | * 任务完成的标记
18 | */
19 | private boolean end;
20 |
21 | /**
22 | * 构造函数,初始化完成服务对象
23 | *
24 | * @param service 完成服务对象
25 | */
26 | public ReportProcessor(CompletionService service) {
27 | this.service = service;
28 | }
29 |
30 |
31 | /**
32 | * 核心方法,如果任务没有完成就一直执行
33 | */
34 | @Override
35 | public void run() {
36 | while (!end) {
37 | try {
38 | // 调用CompletionService接口的poll()方法,获取CompletionService执行的下个已完成任务的Future对象
39 | Future result = service.poll(20, TimeUnit.SECONDS);
40 | if (result != null) {
41 | // 使用Future对象的get()方法获取任务的结果,并且将这些结果写入到控制台
42 | String report = result.get();
43 | System.out.printf("ReportReceiver: Report Received: %s\n", report);
44 | }
45 | } catch (InterruptedException | ExecutionException e) {
46 | e.printStackTrace();
47 | }
48 | }
49 |
50 | System.out.printf("ReportSender: End\n");
51 | }
52 |
53 | /**
54 | * 设置任务完成标记
55 | * @param end 任务完成标记
56 | */
57 | public void setEnd(boolean end) {
58 | this.end = end;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/task/ReportRequest.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.CompletionService;
4 |
5 | /**
6 | * 报告请求类
7 | */
8 | public class ReportRequest implements Runnable {
9 | /**
10 | * 报告请求类的名字
11 | */
12 | private String name;
13 | /**
14 | * 完成任务对象
15 | */
16 | private CompletionService service;
17 |
18 | /**
19 | * 构造函数,初始化报告请求类的名字,完成任务对象
20 | *
21 | * @param name 报告请求类的名字
22 | * @param service 完成任务对象
23 | */
24 | public ReportRequest(String name, CompletionService service) {
25 | this.name = name;
26 | this.service = service;
27 | }
28 |
29 | /**
30 | * 核心方法,创建一个报告生成对象,并且将其提交到完成任务对象
31 | */
32 | @Override
33 | public void run() {
34 | ReportGenerator reportGenerator = new ReportGenerator(name, "Report");
35 | service.submit(reportGenerator);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/04-12-处理在执行器中被拒绝的任务/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.RejectedTaskController;
4 | import com.concurrency.task.Task;
5 |
6 | import java.util.concurrent.Executors;
7 | import java.util.concurrent.ThreadPoolExecutor;
8 |
9 | public class Main {
10 | public static void main(String[] args) {
11 | // 创建拒绝任务控制器对象
12 | // Create the controller for the Rejected tasks
13 | RejectedTaskController controller = new RejectedTaskController();
14 | // 创建执行器对象,并且设置拒绝执行处理器对象
15 | ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
16 | executor.setRejectedExecutionHandler(controller);
17 |
18 | // 运行三个任务
19 | System.out.printf("Main: Starting.\n");
20 | for (int i = 0; i < 3; i++) {
21 | Task task = new Task("Task" + i);
22 | executor.submit(task);
23 | }
24 |
25 | // 关闭执行器
26 | System.out.printf("Main: Shuting down the Executor.\n");
27 | executor.shutdown();
28 |
29 | // 发送另外一个任务
30 | System.out.printf("Main: Sending another Task.\n");
31 | Task task = new Task("RejectedTask");
32 | executor.submit(task);
33 |
34 | // 程序结束
35 | System.out.printf("Main: End.\n");
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/04-12-处理在执行器中被拒绝的任务/src/com/concurrency/task/RejectedTaskController.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.RejectedExecutionHandler;
4 | import java.util.concurrent.ThreadPoolExecutor;
5 |
6 | /**
7 | * 拒绝任务处理器类
8 | */
9 | public class RejectedTaskController implements RejectedExecutionHandler {
10 | /**
11 | * 核心方法,在控制台输出已被拒绝的任务的名称和 执行器的状态。
12 | * @param r
13 | * @param executor
14 | */
15 | @Override
16 | public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
17 | System.out.printf("RejectedTaskController: The task %s has been rejected\n", r.toString());
18 | System.out.printf("RejectedTaskController: %s\n", executor.toString());
19 | System.out.printf("RejectedTaskController: Terminating: %s\n", executor.isTerminating());
20 | System.out.printf("RejectedTasksController: Terminated: %s\n", executor.isTerminated());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/04-12-处理在执行器中被拒绝的任务/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * 任务类,执行一个随机时间的任务
7 | */
8 | public class Task implements Runnable {
9 | private String name;
10 |
11 | public Task(String name) {
12 | this.name = name;
13 | }
14 |
15 | @Override
16 | public void run() {
17 | System.out.printf("Task %s: Starting\n", name);
18 | try {
19 | Long duration = (long) (Math.random() * 10);
20 | System.out.printf("Task %s: ReportGenerator: Generating a report during %d seconds\n", name, duration);
21 | TimeUnit.SECONDS.sleep(duration);
22 | } catch (InterruptedException e) {
23 | e.printStackTrace();
24 | }
25 | System.out.printf("Task %s: Ending\n", name);
26 | }
27 |
28 | @Override
29 | public String toString() {
30 | return name;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/05-02-创建Fork-Join线程池/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Task;
4 | import com.concurrency.utils.Product;
5 | import com.concurrency.utils.ProductListGenerator;
6 |
7 | import java.util.List;
8 | import java.util.concurrent.ForkJoinPool;
9 | import java.util.concurrent.TimeUnit;
10 |
11 | public class Main {
12 | public static void main(String[] args) {
13 | // 创建产品生成器对象,并且门生产10000个产品
14 | ProductListGenerator generator = new ProductListGenerator();
15 | List products = generator.generate(10000);
16 |
17 | // 创建一个任务对象
18 | Task task = new Task(products, 0, products.size(), 0.2);
19 |
20 | // 创建一个分合池
21 | ForkJoinPool pool = new ForkJoinPool();
22 |
23 | // 执行任务
24 | pool.execute(task);
25 |
26 | // 输出分合池的信息
27 | do {
28 | System.out.printf("Main: Thread Count: %d\n", pool.getActiveThreadCount());
29 | System.out.printf("Main: Thread Steal: %d\n", pool.getStealCount());
30 | System.out.printf("Main: Paralelism: %d\n", pool.getParallelism());
31 | try {
32 | TimeUnit.MILLISECONDS.sleep(5);
33 | } catch (InterruptedException e) {
34 | e.printStackTrace();
35 | }
36 | } while (!task.isDone());
37 |
38 | // 关闭分合池
39 | pool.shutdown();
40 |
41 | // 检查任务是否正常完成
42 | if (task.isCompletedNormally()) {
43 | System.out.printf("Main: The process has completed normally.\n");
44 | }
45 |
46 | // 输出价格不是12的产品
47 | for (Product product : products) {
48 | if (product.getPrice() != 12) {
49 | System.out.printf("Product %s: %f\n", product.getName(), product.getPrice());
50 | }
51 | }
52 |
53 | // 结束程序
54 | System.out.println("Main: End of the program.\n");
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/05-02-创建Fork-Join线程池/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.utils.Product;
4 |
5 | import java.util.List;
6 | import java.util.concurrent.RecursiveAction;
7 |
8 | /**
9 | *任务执行类,如果产品多于10个就让分出子任务进行处理
10 | */
11 | public class Task extends RecursiveAction {
12 | private static final long serialVersionUID = 6876633274768462482L;
13 |
14 | /**
15 | * 产品集合对象
16 | */
17 | private List products;
18 | /**
19 | * 处理的第一个产品位置
20 | */
21 | private int first;
22 | /**
23 | * 处理的最后一个产品位置
24 | */
25 | private int last;
26 | /**
27 | * 价格增长率
28 | */
29 | private double increment;
30 |
31 | /**
32 | * 构造函数,初始化属性
33 | *
34 | * @param products 产品集合对象
35 | * @param first 处理的第一个产品位置
36 | * @param last 处理的最后一个产品位置(不包含)
37 | * @param increment 价格增长率
38 | */
39 | public Task(List products, int first, int last, double increment) {
40 | this.products = products;
41 | this.first = first;
42 | this.last = last;
43 | this.increment = increment;
44 | }
45 |
46 | /**
47 | * 对产品进行计算
48 | */
49 | @Override
50 | protected void compute() {
51 | if (last - first < 10) { // 处理的产品数少于10个就提价
52 | updatePrices();
53 | } else { // 否则就让两个子线程去执行
54 | int middle = (first + last) / 2;
55 | System.out.printf("Task: Pending tasks: %s\n", getQueuedTaskCount());
56 | Task t1 = new Task(products, first, middle + 1, increment);
57 | Task t2 = new Task(products, middle + 1, last, increment);
58 | invokeAll(t1, t2);
59 | }
60 | }
61 |
62 | /**
63 | * 更价格,将指定的范围内的产品提价
64 | */
65 | private void updatePrices() {
66 | for (int i = first; i < last; i++) {
67 | Product product = products.get(i);
68 | product.setPrice(product.getPrice() * (1 + increment)); // 按increment比率提价
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/05-02-创建Fork-Join线程池/src/com/concurrency/utils/Product.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.utils;
2 |
3 | /**
4 | * 产品类,保存产品的名称和价格
5 | */
6 | public class Product {
7 | /**
8 | * 名称
9 | */
10 | private String name;
11 | /**
12 | * 价格
13 | */
14 | private double price;
15 |
16 | /**
17 | * 获取产品名称
18 | *
19 | * @return 产品名称
20 | */
21 | public String getName() {
22 | return name;
23 | }
24 |
25 | /**
26 | * 设置产名品名称
27 | *
28 | * @param name 产名名称
29 | */
30 | public void setName(String name) {
31 | this.name = name;
32 | }
33 |
34 | /**
35 | * 获取产品价格
36 | *
37 | * @return 产品价格
38 | */
39 | public double getPrice() {
40 | return price;
41 | }
42 |
43 | /**
44 | * 设置产品价格
45 | *
46 | * @param price 产品价格
47 | */
48 | public void setPrice(double price) {
49 | this.price = price;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/05-02-创建Fork-Join线程池/src/com/concurrency/utils/ProductListGenerator.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.utils;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 产品生成器类,根据指定的数量创建产品
8 | */
9 | public class ProductListGenerator {
10 |
11 | /**
12 | * 产品生产类
13 | *
14 | * @param size 产品数量
15 | * @return 产品集合
16 | */
17 | public List generate(int size) {
18 | List ret = new ArrayList<>();
19 | for (int i = 0; i < size; i++) {
20 | Product product = new Product();
21 | product.setName("Product " + i);
22 | product.setPrice(10);
23 | ret.add(product);
24 | }
25 |
26 | return ret;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/05-03-合并任务的结果/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.DocumentTask;
4 | import com.concurrency.utils.DocumentMock;
5 |
6 | import java.util.concurrent.ExecutionException;
7 | import java.util.concurrent.ForkJoinPool;
8 | import java.util.concurrent.TimeUnit;
9 |
10 | public class Main {
11 | public static void main(String[] args) {
12 | // 创建一个模拟文档,他有100行,每行1000个单词
13 | // Generate a document with 100 lines and 1000 words per line
14 | DocumentMock mock = new DocumentMock();
15 | String[][] document = mock.generateDocument(100, 1000, "the");
16 |
17 | // 创建一个文档任务对象,处理整个文档
18 | DocumentTask task = new DocumentTask(document, 0, 100, "the");
19 |
20 | // 创建一个分合池对象
21 | ForkJoinPool pool = new ForkJoinPool();
22 |
23 | // 执行文档处理任务
24 | pool.execute(task);
25 |
26 | // 输出分合池对象的统计数据
27 | do {
28 | System.out.printf("******************************************\n");
29 | System.out.printf("Main: Parallelism: %d\n", pool.getParallelism());
30 | System.out.printf("Main: Active Threads: %d\n", pool.getActiveThreadCount());
31 | System.out.printf("Main: Task Count: %d\n", pool.getQueuedTaskCount());
32 | System.out.printf("Main: Steal Count: %d\n", pool.getStealCount());
33 | System.out.printf("******************************************\n");
34 |
35 | try {
36 | TimeUnit.SECONDS.sleep(1);
37 | } catch (InterruptedException e) {
38 | e.printStackTrace();
39 | }
40 |
41 | } while (!task.isDone());
42 |
43 | // 关闭分合池
44 | pool.shutdown();
45 |
46 | // 等待所有的任务完成
47 | try {
48 | pool.awaitTermination(1, TimeUnit.DAYS);
49 | } catch (InterruptedException e) {
50 | e.printStackTrace();
51 | }
52 |
53 | // 输出任务完成的结果
54 | try {
55 | System.out.printf("Main: The word appears %d in the document", task.get());
56 | } catch (InterruptedException | ExecutionException e) {
57 | e.printStackTrace();
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/05-03-合并任务的结果/src/com/concurrency/task/DocumentTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.concurrent.ExecutionException;
6 | import java.util.concurrent.RecursiveTask;
7 |
8 | /**
9 | * 文档处理类,在文档中查找指定的单词
10 | */
11 | public class DocumentTask extends RecursiveTask {
12 | private static final long serialVersionUID = -1257254196502539272L;
13 | /**
14 | * 等待处理的文档
15 | */
16 | private String document[][];
17 | /**
18 | * 文档处理的开始行
19 | */
20 | private int start;
21 | /**
22 | * 文档处理的结束行
23 | */
24 | private int end;
25 |
26 | /**
27 | * 要查找的单词
28 | */
29 | private String word;
30 |
31 | /**
32 | * 构造函数
33 | *
34 | * @param document 等待处理的文档
35 | * @param start 文档处理的开始行
36 | * @param end 文档处理的结束行
37 | * @param word 要查找的单词
38 | */
39 | public DocumentTask(String document[][], int start, int end, String word) {
40 | this.document = document;
41 | this.start = start;
42 | this.end = end;
43 | this.word = word;
44 | }
45 |
46 |
47 | /**
48 | * 核心方法,统计文档的中指定的单词
49 | *
50 | * @return 指定的单词出现的次数
51 | */
52 | @Override
53 | protected Integer compute() {
54 | Integer result = null;
55 | if (end - start < 10) { // 少于10行,使用行处理方法
56 | result = processLines(document, start, end, word);
57 | } else { // 否则使用两个线程去处理
58 | int mid = (start + end) / 2;
59 | DocumentTask task1 = new DocumentTask(document, start, mid, word);
60 | DocumentTask task2 = new DocumentTask(document, mid, end, word);
61 | invokeAll(task1, task2);
62 | try {
63 | result = groupResults(task1.get(), task2.get());
64 | } catch (InterruptedException | ExecutionException e) {
65 | e.printStackTrace();
66 | }
67 | }
68 | return result;
69 | }
70 |
71 | /**
72 | * 返回number1+number2的和
73 | *
74 | * @param number1 加数l
75 | * @param number2 加数2
76 | * @return 和
77 | */
78 | private Integer groupResults(Integer number1, Integer number2) {
79 | return number1 + number2;
80 | }
81 |
82 | /**
83 | * 行处理方法
84 | *
85 | * @param document 等待处理的文档
86 | * @param start 文档处理的开始行
87 | * @param end 文档处理的结束行
88 | * @param word 要查找的单词
89 | * @return 指定的单词出现的次数
90 | */
91 | private Integer processLines(String[][] document, int start, int end, String word) {
92 | List tasks = new ArrayList();
93 |
94 | // 有多少行就创建多少个行处理任务对象
95 | for (int i = start; i < end; i++) {
96 | LineTask task = new LineTask(document[i], 0, document[i].length, word);
97 | tasks.add(task);
98 | }
99 | invokeAll(tasks);
100 |
101 | // 统计结果
102 | int result = 0;
103 | for (LineTask task : tasks) {
104 | try {
105 | result = result + task.get();
106 | } catch (InterruptedException | ExecutionException e) {
107 | e.printStackTrace();
108 | }
109 | }
110 | return result;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/05-03-合并任务的结果/src/com/concurrency/task/LineTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.List;
4 | import java.util.concurrent.ExecutionException;
5 | import java.util.concurrent.RecursiveTask;
6 | import java.util.concurrent.TimeUnit;
7 |
8 | /**
9 | * 行处理类,处理指定行数和单词
10 | */
11 | public class LineTask extends RecursiveTask {
12 | private static final long serialVersionUID = 4169105159737293155L;
13 | /**
14 | * 文档中一行数据
15 | */
16 | private String line[];
17 |
18 | /**
19 | * 行处理的起始位置
20 | */
21 | private int start;
22 | /**
23 | * 行处理的结束位置
24 | */
25 | private int end;
26 |
27 | /**
28 | * 要查找的单词
29 | */
30 | private String word;
31 |
32 | /**
33 | * 构造函数
34 | *
35 | * @param line 文档中一行数据
36 | * @param start 行处理的起始位置
37 | * @param end 行处理的结束位置
38 | * @param word 要查找的单词
39 | */
40 | public LineTask(String line[], int start, int end, String word) {
41 | this.line = line;
42 | this.start = start;
43 | this.end = end;
44 | this.word = word;
45 | }
46 |
47 | /**
48 | * 核心方法,完成单词的查找
49 | *
50 | * @return 查找范围内,单词出现的次数
51 | */
52 | @Override
53 | protected Integer compute() {
54 | Integer result = null;
55 | if (end - start < 100) { // 少于100个单词就进行统计
56 | result = count(line, start, end, word);
57 | } else { // 否则就分成两个线程进行处理
58 | int mid = (start + end) / 2;
59 | LineTask task1 = new LineTask(line, start, mid + 1, word);
60 | LineTask task2 = new LineTask(line, mid + 1, end, word);
61 | invokeAll(task1, task2);
62 |
63 | try {
64 | result = groupResults(task1.get(), task2.get());
65 | } catch (InterruptedException | ExecutionException e) {
66 | e.printStackTrace();
67 | }
68 | }
69 | return result;
70 | }
71 |
72 | /**
73 | * 返回number1+number2的和
74 | *
75 | * @param number1 加数l
76 | * @param number2 加数2
77 | * @return 和
78 | */
79 | private Integer groupResults(Integer number1, Integer number2) {
80 | return number1 + number2;
81 | }
82 |
83 | /**
84 | * 统计单词出现的次数
85 | *
86 | * @param line 待待查找的行
87 | * @param start 处理的开始位置
88 | * @param end 处理的结束位置
89 | * @param word 查找的单词
90 | * @return 单词出现的次数
91 | */
92 | private Integer count(String[] line, int start, int end, String word) {
93 | int counter;
94 | counter = 0;
95 | for (int i = start; i < end; i++) {
96 | if (line[i].equals(word)) {
97 | counter++;
98 | }
99 | }
100 | try {
101 | TimeUnit.MILLISECONDS.sleep(10);
102 | } catch (InterruptedException e) {
103 | e.printStackTrace();
104 | }
105 | return counter;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/05-03-合并任务的结果/src/com/concurrency/utils/DocumentMock.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.utils;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * 文档模拟对象,根据指定的列数和每行单词数生成文档
7 | */
8 | public class DocumentMock {
9 | /**
10 | * 文档中的单词集合
11 | */
12 | private String words[] = {"the", "hello", "goodbye", "packt", "java", "thread", "pool", "random", "class", "main"};
13 |
14 | /**
15 | * 生成文档
16 | *
17 | * @param numLines 文档行数
18 | * @param numWords 每行单词数
19 | * @param word 文档中要查找的单词
20 | * @return 文档
21 | */
22 | public String[][] generateDocument(int numLines, int numWords, String word) {
23 |
24 | int counter = 0;
25 | String document[][] = new String[numLines][numWords];
26 | Random random = new Random();
27 | for (int i = 0; i < numLines; i++) {
28 | for (int j = 0; j < numWords; j++) {
29 | int index = random.nextInt(words.length);
30 | document[i][j] = words[index];
31 | if (document[i][j].equals(word)) {
32 | counter++;
33 | }
34 | }
35 | }
36 | System.out.printf("DocumentMock: The word appears %d times in the document.\n", counter);
37 | return document;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/05-04-异步运行任务/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.FolderProcessor;
4 |
5 | import java.util.List;
6 | import java.util.concurrent.ForkJoinPool;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | public class Main {
10 | public static void main(String[] args) {
11 | // 创建分合池
12 | ForkJoinPool pool = new ForkJoinPool();
13 |
14 | // 为三个不同的文件夹创建文件处理器对象
15 | FolderProcessor system = new FolderProcessor("C:\\Windows", "log");
16 | FolderProcessor apps = new FolderProcessor("C:\\Program Files", "log");
17 | FolderProcessor documents = new FolderProcessor("C:\\Documents And Settings", "log");
18 |
19 | // 在分合池中执行一个任务
20 | pool.execute(system);
21 | pool.execute(apps);
22 | pool.execute(documents);
23 |
24 | // 输出统计信息,直到三个任务都完成
25 | do {
26 | System.out.printf("******************************************\n");
27 | System.out.printf("Main: Parallelism: %d\n", pool.getParallelism());
28 | System.out.printf("Main: Active Threads: %d\n", pool.getActiveThreadCount());
29 | System.out.printf("Main: Task Count: %d\n", pool.getQueuedTaskCount());
30 | System.out.printf("Main: Steal Count: %d\n", pool.getStealCount());
31 | System.out.printf("******************************************\n");
32 | try {
33 | TimeUnit.SECONDS.sleep(1);
34 | } catch (InterruptedException e) {
35 | e.printStackTrace();
36 | }
37 | } while ((!system.isDone()) || (!apps.isDone()) || (!documents.isDone()));
38 |
39 | // 关闭分合池
40 | pool.shutdown();
41 |
42 | // 保存每个任务统计的结束
43 | List results;
44 |
45 | results = system.join();
46 | System.out.printf("System: %d files found.\n", results.size());
47 |
48 | results = apps.join();
49 | System.out.printf("Apps: %d files found.\n", results.size());
50 |
51 | results = documents.join();
52 | System.out.printf("Documents: %d files found.\n", results.size());
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/05-04-异步运行任务/src/com/concurrency/task/FolderProcessor.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.io.File;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.concurrent.RecursiveTask;
7 |
8 | /**
9 | * 文件夹处理类,查找指定文件夹及其子文件夹下的指定后缀名的文件
10 | */
11 | public class FolderProcessor extends RecursiveTask> {
12 | private static final long serialVersionUID = -6119741136325003142L;
13 | /**
14 | * 开始处理的文件目录
15 | */
16 | private String path;
17 |
18 | /**
19 | * 要查找的文件后缀名
20 | */
21 | private String extension;
22 |
23 | /**
24 | * 构造函数
25 | *
26 | * @param path 开始处理的文件目录
27 | * @param extension 要查找的文件后缀名
28 | */
29 | public FolderProcessor(String path, String extension) {
30 | this.path = path;
31 | this.extension = extension;
32 | }
33 |
34 | /**
35 | * 核心方法,查找文件夹下所有指定后缀的文件,如果是一个文件夹就开创建子线程去运行
36 | *
37 | * @return 查找到的文件集合
38 | */
39 | @Override
40 | protected List compute() {
41 | List list = new ArrayList<>();
42 | List tasks = new ArrayList<>();
43 | File file = new File(path);
44 | File content[] = file.listFiles();
45 | if (content != null) {
46 | for (int i = 0; i < content.length; i++) {
47 | if (content[i].isDirectory()) {
48 | FolderProcessor task = new FolderProcessor(content[i].getAbsolutePath(), extension);
49 | task.fork();
50 | tasks.add(task);
51 | } else {
52 | if (checkFile(content[i].getName())) {
53 | list.add(content[i].getAbsolutePath());
54 | }
55 | }
56 | }
57 |
58 | if (tasks.size() > 50) {
59 | System.out.printf("%s: %d tasks ran.\n", file.getAbsolutePath(), tasks.size());
60 | }
61 | addResultsFromTasks(list, tasks);
62 | }
63 |
64 | return list;
65 | }
66 |
67 | /**
68 | * 汇总统计结果
69 | *
70 | * @param list 结果存放的集合
71 | * @param tasks 任务集合
72 | */
73 | private void addResultsFromTasks(List list, List tasks) {
74 | for (FolderProcessor item : tasks) {
75 | list.addAll(item.join());
76 | }
77 | }
78 |
79 | /**
80 | * 检查文件是否以指定的名称结束
81 | *
82 | * @param name 文件扩展名
83 | * @return true以指定的名字结束,false不以指定的名字结束
84 | */
85 | private boolean checkFile(String name) {
86 | return name.endsWith(extension);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/05-05-在任务中抛出异常/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Task;
4 |
5 | import java.util.concurrent.ForkJoinPool;
6 | import java.util.concurrent.TimeUnit;
7 |
8 | public class Main {
9 | public static void main(String[] args) {
10 | // 创建长度为100的整形数组
11 | int array[] = new int[100];
12 | // 创建处理数组的任务
13 | Task task = new Task(array, 0, 100);
14 | // 创建分合池对象去执行这个任务
15 | ForkJoinPool pool = new ForkJoinPool();
16 |
17 | // 执行任务
18 | pool.execute(task);
19 |
20 | // 关闭分合池
21 | pool.shutdown();
22 |
23 | // 等待任务的完成
24 | try {
25 | pool.awaitTermination(1, TimeUnit.DAYS);
26 | } catch (InterruptedException e) {
27 | e.printStackTrace();
28 | }
29 |
30 | // 检查是否抛出异常,如果抛出异常就输出信息
31 | if (task.isCompletedAbnormally()) {
32 | System.out.printf("Main: An exception has ocurred\n");
33 | System.out.printf("Main: %s\n", task.getException());
34 | }
35 |
36 | System.out.printf("Main: Result: %d", task.join());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/05-05-在任务中抛出异常/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.RecursiveTask;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 任务执行方法
8 | */
9 | public class Task extends RecursiveTask {
10 | /**
11 | * 序列化版本号
12 | */
13 | private static final long serialVersionUID = 1L;
14 |
15 | /**
16 | * 待处理的数组
17 | */
18 | private int array[];
19 |
20 | /**
21 | * 任务处理的起始位置
22 | */
23 | private int start;
24 | /**
25 | * 任务处理的结束位置
26 | */
27 | private int end;
28 |
29 | /**
30 | * 构造函数
31 | *
32 | * @param array 待处理的数组
33 | * @param start 任务处理的起始位置
34 | * @param end 任务处理的结束位置
35 | */
36 | public Task(int array[], int start, int end) {
37 | this.array = array;
38 | this.start = start;
39 | this.end = end;
40 | }
41 |
42 | /**
43 | * 核心方法,如果处理的元素大于9个就分成两个任务去执行它,如果处理的起始位置小于3,结束位置大于3就抛出异常
44 | */
45 | @Override
46 | protected Integer compute() {
47 | System.out.printf("Task: Start from %d to %d\n", start, end);
48 | if (end - start < 10) {
49 | if ((3 > start) && (3 < end)) {
50 | throw new RuntimeException("This task throws an Exception: Task from " + start + " to " + end);
51 | }
52 |
53 | try {
54 | TimeUnit.SECONDS.sleep(1);
55 | } catch (InterruptedException e) {
56 | e.printStackTrace();
57 | }
58 |
59 | } else {
60 | int mid = (end + start) / 2;
61 | Task task1 = new Task(array, start, mid);
62 | Task task2 = new Task(array, mid, end);
63 | invokeAll(task1, task2);
64 | System.out.printf("Task: Result form %d to %d: %d\n", start, mid, task1.join());
65 | System.out.printf("Task: Result form %d to %d: %d\n", mid, end, task2.join());
66 | }
67 | System.out.printf("Task: End form %d to %d\n", start, end);
68 | return 0;
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/05-06-取消任务/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.TaskManager;
4 | import com.concurrency.utils.ArrayGenerator;
5 | import com.concurrency.utils.SearchNumberTask;
6 |
7 | import java.util.concurrent.ForkJoinPool;
8 | import java.util.concurrent.TimeUnit;
9 |
10 | public class Main {
11 | public static void main(String[] args) {
12 | // 创建一个数组生成器对象,生成一个长度为1000的整形数组
13 | ArrayGenerator generator = new ArrayGenerator();
14 | int array[] = generator.generateArray(1000);
15 |
16 | // 创建一个任务管理对象
17 | TaskManager manager = new TaskManager();
18 |
19 | // 使用默认的构造函数,创建一个分合池对象
20 | ForkJoinPool pool = new ForkJoinPool();
21 |
22 | // 创建一个处理任务的数组
23 | SearchNumberTask task = new SearchNumberTask(array, 0, 1000, 5, manager);
24 |
25 | //执行任务
26 | pool.execute(task);
27 |
28 | // 关闭这个池
29 | pool.shutdown();
30 |
31 |
32 | // 等待任务完成
33 | try {
34 | pool.awaitTermination(1, TimeUnit.DAYS);
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }
38 |
39 | // 输出信息,表示程序已经完成
40 | System.out.printf("Main: The program has finished\n");
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/05-06-取消任务/src/com/concurrency/task/TaskManager.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.utils.SearchNumberTask;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import java.util.concurrent.ForkJoinTask;
8 |
9 | /**
10 | * 任务管理类
11 | */
12 | public class TaskManager {
13 | /**
14 | * 任务列表对象
15 | */
16 | private List> tasks;
17 |
18 | /**
19 | * 构造函数,初始化任务值列表对象
20 | */
21 | public TaskManager(){
22 | tasks=new ArrayList<>();
23 | }
24 |
25 | /**
26 | * 在列表中添加一个新的任务
27 | * @param task 新的任务
28 | */
29 | public void addTask(ForkJoinTask task){
30 | tasks.add(task);
31 | }
32 |
33 | /**
34 | * 取消队列中的指定任务
35 | * @param cancelTask 指定的任务
36 | */
37 | public void cancelTasks(ForkJoinTask cancelTask){
38 | for (ForkJoinTask task :tasks) {
39 | if (task!=cancelTask) {
40 | task.cancel(true);
41 | ((SearchNumberTask)task).writeCancelMessage();
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/05-06-取消任务/src/com/concurrency/utils/ArrayGenerator.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.utils;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * 整形数组生成类
7 | */
8 | public class ArrayGenerator {
9 | /**
10 | * 生成整形数组,生成的值在[0, size)
11 | * @param size 数组长度
12 | * @return 长度为size的数组
13 | */
14 | public int[] generateArray(int size) {
15 | int array[] = new int[size];
16 | Random random = new Random();
17 | for (int i = 0; i < size; i++) {
18 | array[i] = random.nextInt(10);
19 | }
20 | return array;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/06-02-使用非阻塞式线程安全列表/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.AddTask;
4 | import com.concurrency.task.PollTask;
5 |
6 | import java.util.concurrent.ConcurrentLinkedDeque;
7 |
8 | public class Main {
9 | public static void main(String[] args) throws Exception {
10 | // 创建一个并发双向队列对象
11 | ConcurrentLinkedDeque list = new ConcurrentLinkedDeque<>();
12 | // 创建长度为100的线程数组
13 | Thread threads[] = new Thread[100];
14 |
15 | // 创建100个AddTask对象,并且让他们在各自的线程中运行
16 | for (int i = 0; i < threads.length; i++) {
17 | AddTask task = new AddTask(list);
18 | threads[i] = new Thread(task);
19 | threads[i].start();
20 | }
21 | System.out.printf("Main: %d AddTask threads have been launched\n", threads.length);
22 |
23 | // 等待所有的线程执行完
24 | for (Thread thread : threads) {
25 | thread.join();
26 | }
27 |
28 | // 输出队列长度信息
29 | System.out.printf("Main: Size of the List: %d\n", list.size());
30 |
31 | // 创建100个PollTask对象,并且让他们在各自的线程中运行
32 | for (int i = 0; i < threads.length; i++) {
33 | PollTask task = new PollTask(list);
34 | threads[i] = new Thread(task);
35 | threads[i].start();
36 | }
37 | System.out.printf("Main: %d PollTask threads have been launched\n", threads.length);
38 |
39 | // 等待线程执行完
40 | for (Thread thread : threads) {
41 | thread.join();
42 | }
43 |
44 | // 输出队列长度信息
45 | System.out.printf("Main: Size of the List: %d\n", list.size());
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/06-02-使用非阻塞式线程安全列表/src/com/concurrency/task/AddTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.ConcurrentLinkedDeque;
4 |
5 | /**
6 | * 添加数据任务类,向并发队列中添加10000个数据
7 | */
8 | public class AddTask implements Runnable {
9 |
10 | /**
11 | * 等待添加数组的队列
12 | */
13 | private ConcurrentLinkedDeque list;
14 |
15 | /**
16 | * 构造函数
17 | *
18 | * @param list 等待添加数组的队列
19 | */
20 | public AddTask(ConcurrentLinkedDeque list) {
21 | this.list = list;
22 | }
23 |
24 | /**
25 | * 核心方法,向并发队列中添加10000个数据
26 | */
27 | @Override
28 | public void run() {
29 | String name = Thread.currentThread().getName();
30 | for (int i = 0; i < 10000; i++) {
31 | list.add(name + ": Element " + i);
32 | }
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/06-02-使用非阻塞式线程安全列表/src/com/concurrency/task/PollTask.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.ConcurrentLinkedDeque;
4 |
5 | /**
6 | * 取数据任务类,从并发队列中删除10000个数据
7 | */
8 | public class PollTask implements Runnable {
9 |
10 | /**
11 | * 待删除元素的队列
12 | */
13 | private ConcurrentLinkedDeque list;
14 |
15 | /**
16 | * 构造函数
17 | *
18 | * @param list 待删除元素的队列
19 | */
20 | public PollTask(ConcurrentLinkedDeque list) {
21 | this.list = list;
22 | }
23 |
24 | /**
25 | * 核心方法,在并发队列的头部和尾部各删除5000个元素
26 | */
27 | @Override
28 | public void run() {
29 | for (int i = 0; i < 5000; i++) {
30 | list.pollFirst();
31 | list.pollLast();
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/06-03-使用阻塞式线程安全列表/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Client;
4 |
5 | import java.util.Date;
6 | import java.util.concurrent.LinkedBlockingDeque;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | public class Main {
10 | public static void main(String[] args) throws Exception {
11 | // 创建一个并发链式双向队列
12 | LinkedBlockingDeque list = new LinkedBlockingDeque<>(3);
13 |
14 | Client client = new Client(list);
15 | Thread thread = new Thread(client);
16 | thread.start();
17 |
18 | for (int i = 0; i < 5; i++) {
19 | for (int j = 0; j < 3; j++) {
20 | String request = list.take();
21 | System.out.printf("Main: Request: %s at %s. Size: %d\n", request, new Date(), list.size());
22 | }
23 | TimeUnit.MILLISECONDS.sleep(300);
24 | }
25 |
26 | System.out.printf("Main: End of the program.\n");
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/06-03-使用阻塞式线程安全列表/src/com/concurrency/task/Client.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/06-03-使用阻塞式线程安全列表/src/com/concurrency/task/Client.java
--------------------------------------------------------------------------------
/06-04-使用按优先级排序的阻塞式线程安全列表/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Event;
4 | import com.concurrency.task.Task;
5 |
6 | import java.util.concurrent.PriorityBlockingQueue;
7 |
8 | public class Main {
9 | public static void main(String[] args) {
10 |
11 | // 存储事件的优先级队列
12 | PriorityBlockingQueue queue = new PriorityBlockingQueue<>();
13 |
14 |
15 | // 存储5个线程对象的数组
16 | Thread taskThreads[] = new Thread[5];
17 |
18 |
19 | // 创建5个线程运行5个任务,每个任务创建1000事件对象
20 | for (int i = 0; i < taskThreads.length; i++) {
21 | Task task = new Task(i, queue);
22 | taskThreads[i] = new Thread(task);
23 | }
24 |
25 |
26 | // 启动5个线程
27 | for (Thread taskThread : taskThreads) {
28 | taskThread.start();
29 | }
30 |
31 | // 等待5个线程完成
32 | for (Thread taskThread : taskThreads) {
33 | try {
34 | taskThread.join();
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 |
40 | // 输出事件信息
41 | System.out.printf("Main: Queue Size: %d\n", queue.size());
42 | for (int i = 0; i < taskThreads.length * 1000; i++) {
43 | Event event = queue.poll();
44 | System.out.printf("Thread %s: Priority %d\n", event.getThread(), event.getPriority());
45 | }
46 | System.out.printf("Main: Queue Size: %d\n", queue.size());
47 | System.out.printf("Main: End of the program\n");
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/06-04-使用按优先级排序的阻塞式线程安全列表/src/com/concurrency/task/Event.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.sun.istack.internal.NotNull;
4 |
5 | /**
6 | * 事件类,存储一个件事的属性,它包括一个事件的优先级,这个类实现了Comparable接口的方法,
7 | * 用来确定哪个事件对象的优先级更高
8 | */
9 | public class Event implements Comparable {
10 |
11 | /**
12 | * 线程编号
13 | */
14 | private int thread;
15 | /**
16 | * 线程优先级
17 | */
18 | private int priority;
19 |
20 | /**
21 | * 构造构造,用于初始化属性
22 | *
23 | * @param thread 产生事件的线程编号
24 | * @param priority 事件的优先级
25 | */
26 | public Event(int thread, int priority) {
27 | this.thread = thread;
28 | this.priority = priority;
29 | }
30 |
31 | /**
32 | * 获取线程编号
33 | *
34 | * @return 线程编号
35 | */
36 | public int getThread() {
37 | return thread;
38 | }
39 |
40 | /**
41 | * 获取线程优先级
42 | *
43 | * @return 线程优先级
44 | */
45 | public int getPriority() {
46 | return priority;
47 | }
48 |
49 | /**
50 | * 比较那个线程的优先级更高
51 | */
52 | @Override
53 | public int compareTo(Event e) {
54 | if (this.priority > e.getPriority()) {
55 | return -1;
56 | } else if (this.priority < e.getPriority()) {
57 | return 1;
58 | } else {
59 | return 0;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/06-04-使用按优先级排序的阻塞式线程安全列表/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.PriorityBlockingQueue;
4 |
5 | /**
6 | * 任务对象,生成1000个事件,并且将其存放在一个优先队列中
7 | */
8 | public class Task implements Runnable {
9 |
10 | /**
11 | * 任务编号
12 | */
13 | private int id;
14 |
15 | /**
16 | * 存储事件的优先队列
17 | */
18 | private PriorityBlockingQueue queue;
19 |
20 | /**
21 | * 构造函数,初始化属性
22 | *
23 | * @param id 任务编号
24 | * @param queue 存储事件的优先队列
25 | */
26 | public Task(int id, PriorityBlockingQueue queue) {
27 | this.id = id;
28 | this.queue = queue;
29 | }
30 |
31 | /**
32 | * 核心方法,生成1000个事件,并且将其存放在一个优先队列中
33 | */
34 | @Override
35 | public void run() {
36 | for (int i = 0; i < 1000; i++) {
37 | Event event = new Event(id, i);
38 | queue.add(event);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/06-05-使用带有延迟元素的线程安全列表/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Event;
4 | import com.concurrency.task.Task;
5 |
6 | import java.util.Date;
7 | import java.util.concurrent.DelayQueue;
8 | import java.util.concurrent.TimeUnit;
9 |
10 | public class Main {
11 | public static void main(String[] args) throws Exception {
12 | // 存储事件的延迟队列
13 | DelayQueue queue = new DelayQueue<>();
14 |
15 | // 线程数组
16 | Thread threads[] = new Thread[5];
17 |
18 | // 创建5个任务对象,并且放在不同的线程中去执行
19 | for (int i = 0; i < threads.length; i++) {
20 | Task task = new Task(i + 1, queue);
21 | threads[i] = new Thread(task);
22 | }
23 |
24 | // 启动线程
25 | for (Thread thread : threads) {
26 | thread.start();
27 | }
28 |
29 | // 等待5个任务的完成
30 | for (Thread thread : threads) {
31 | thread.join();
32 | }
33 |
34 | // 输出结果
35 | do {
36 | int counter = 0;
37 | Event event;
38 | do { // 取队列中的所有数据
39 | event = queue.poll();
40 | if (event != null) {
41 | counter++;
42 | }
43 | } while (event != null);
44 | System.out.printf("At %s you have read %d events\n", new Date(), counter);
45 | TimeUnit.MILLISECONDS.sleep(500);
46 | } while (queue.size() > 0);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/06-05-使用带有延迟元素的线程安全列表/src/com/concurrency/task/Event.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.Delayed;
5 | import java.util.concurrent.TimeUnit;
6 |
7 | /**
8 | * 事件类,实现了延迟队列接口
9 | */
10 | public class Event implements Delayed {
11 |
12 | /**
13 | * 激活事件的时间
14 | */
15 | private Date startDate;
16 |
17 | /**
18 | * 构造函数
19 | *
20 | * @param startDate 激活事件的时间
21 | */
22 | public Event(Date startDate) {
23 | this.startDate = startDate;
24 | }
25 |
26 | /**
27 | * 比较两个事件
28 | */
29 | @Override
30 | public int compareTo(Delayed o) {
31 | long result = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
32 | if (result < 0) {
33 | return -1;
34 | } else if (result > 0) {
35 | return 1;
36 | }
37 | return 0;
38 | }
39 |
40 | /**
41 | * 返回离激活时间还剩余的毫秒数
42 | */
43 | @Override
44 | public long getDelay(TimeUnit unit) {
45 | Date now = new Date();
46 | long diff = startDate.getTime() - now.getTime();
47 | return unit.convert(diff, TimeUnit.MILLISECONDS);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/06-05-使用带有延迟元素的线程安全列表/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.Date;
4 | import java.util.concurrent.DelayQueue;
5 |
6 | /**
7 | * 任务类,其事件存储在一个延迟队列中
8 | */
9 | public class Task implements Runnable {
10 |
11 | /**
12 | * 任务编号
13 | */
14 | private int id;
15 |
16 | /**
17 | * 存储事件的任务队列
18 | */
19 | private DelayQueue queue;
20 |
21 | /**
22 | * 构造函数,初始化属性
23 | *
24 | * @param id 任务编号
25 | * @param queue 存储事件的任务队列
26 | */
27 | public Task(int id, DelayQueue queue) {
28 | this.id = id;
29 | this.queue = queue;
30 | }
31 |
32 |
33 | /**
34 | * 核心方法,产生100事件,每个事件有相同的激活时间,将这些事件存储在延迟队列中
35 | */
36 | @Override
37 | public void run() {
38 |
39 | Date now = new Date();
40 | Date delay = new Date();
41 | delay.setTime(now.getTime() + (id * 1000));
42 |
43 | System.out.printf("Thread %s: %s\n", id, delay);
44 |
45 | for (int i = 0; i < 100; i++) {
46 | Event event = new Event(delay);
47 | queue.add(event);
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/06-06-使用线程安全可遍历映射/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Task;
4 | import com.concurrency.utils.Contact;
5 |
6 | import java.util.Map;
7 | import java.util.concurrent.ConcurrentNavigableMap;
8 | import java.util.concurrent.ConcurrentSkipListMap;
9 |
10 | public class Main {
11 | public static void main(String[] args) {
12 | // 创建一个可遍历的映射对象
13 | ConcurrentSkipListMap map;
14 | map = new ConcurrentSkipListMap<>();
15 |
16 | // 创建长度为25的线程数组
17 | Thread threads[] = new Thread[25];
18 | int counter = 0;
19 |
20 | // 在25个不同的线程中执行25个任务
21 | for (char i = 'A'; i < 'Z'; i++) {
22 | Task task = new Task(map, String.valueOf(i));
23 | threads[counter] = new Thread(task);
24 | threads[counter].start();
25 | counter++;
26 | }
27 |
28 | // 等待任务执行完成
29 | for (Thread thread : threads) {
30 | try {
31 | thread.join();
32 | } catch (InterruptedException e) {
33 | e.printStackTrace();
34 | }
35 | }
36 |
37 | // 输出映射的大小
38 | System.out.printf("Main: Size of the map: %d\n", map.size());
39 |
40 | // 保存映射条目的对象
41 | Map.Entry element;
42 | // 保存联系人的对象
43 | Contact contact;
44 |
45 | element = map.firstEntry();
46 | contact = element.getValue();
47 | System.out.printf("Main: First Entry: %s: %s\n", contact.getName(), contact.getPhone());
48 |
49 | // 输出最后一个映射条目
50 | element = map.lastEntry();
51 | contact = element.getValue();
52 | System.out.printf("Main: Last Entry: %s: %s\n", contact.getName(), contact.getPhone());
53 |
54 | // 输出映射的字集
55 | System.out.printf("Main: Submap from A1996 to B1002: \n");
56 | ConcurrentNavigableMap submap = map.subMap("A1996", "B1002");
57 | do {
58 | element = submap.pollFirstEntry();
59 | if (element != null) {
60 | contact = element.getValue();
61 | System.out.printf("%s: %s\n", contact.getName(), contact.getPhone());
62 | }
63 | } while (element != null);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/06-06-使用线程安全可遍历映射/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import com.concurrency.utils.Contact;
4 |
5 | import java.util.concurrent.ConcurrentSkipListMap;
6 |
7 | /**
8 | * 任务类,将联系人存储在一个可遍历的图中
9 | */
10 | public class Task implements Runnable {
11 |
12 | /**
13 | * 存储联系人的可遍历的映射
14 | */
15 | private ConcurrentSkipListMap map;
16 |
17 | /**
18 | * 任务编号
19 | */
20 | private String id;
21 |
22 | /**
23 | * 构造函数,初始化属性
24 | *
25 | * @param map 存储联系人的可遍历的映射
26 | * @param id 任务编号
27 | */
28 | public Task(ConcurrentSkipListMap map, String id) {
29 | this.id = id;
30 | this.map = map;
31 | }
32 |
33 | /**
34 | * 核心方法,产生1000个联系人,并且交它们存储在一个可遍历的映射中
35 | */
36 | @Override
37 | public void run() {
38 | for (int i = 0; i < 1000; i++) {
39 | Contact contact = new Contact(id, String.valueOf(i + 1000));
40 | map.put(id + contact.getPhone(), contact);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/06-06-使用线程安全可遍历映射/src/com/concurrency/utils/Contact.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.utils;
2 |
3 | /**
4 | * 联系人类
5 | */
6 | public class Contact {
7 |
8 | /**
9 | * 联系人的名称
10 | */
11 | private String name;
12 |
13 | /**
14 | * 联系人的电话
15 | */
16 | private String phone;
17 |
18 | /**
19 | * 构造函数
20 | *
21 | * @param name 联系人的名称
22 | * @param phone 联系人的电话
23 | */
24 | public Contact(String name, String phone) {
25 | this.name = name;
26 | this.phone = phone;
27 | }
28 |
29 | /**
30 | * 获取 联系人的名称
31 | *
32 | * @return 联系人的名称
33 | */
34 | public String getName() {
35 | return name;
36 | }
37 |
38 | /**
39 | * 获取联系人的电话
40 | *
41 | * @return 联系人的电话
42 | */
43 | public String getPhone() {
44 | return phone;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/06-07-生成并发随机数/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.TaskLocalRandom;
4 |
5 | public class Main {
6 | public static void main(String[] args) {
7 | // 长度为3的线程数组
8 | Thread threads[] = new Thread[3];
9 |
10 | // 创建线程并且运行任务
11 | for (int i = 0; i < threads.length; i++) {
12 | TaskLocalRandom task = new TaskLocalRandom();
13 | threads[i] = new Thread(task);
14 | threads[i].start();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/06-07-生成并发随机数/src/com/concurrency/task/TaskLocalRandom.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.ThreadLocalRandom;
4 |
5 | /**
6 | * 产生随机数的任务类
7 | */
8 | public class TaskLocalRandom implements Runnable {
9 |
10 | /**
11 | * 构造函数,初始化当前类的随机数生成对象
12 | */
13 | public TaskLocalRandom() {
14 | ThreadLocalRandom.current();
15 | }
16 |
17 | /**
18 | * 核心方法,生成一个[0, 10)的随机数
19 | */
20 | @Override
21 | public void run() {
22 | String name = Thread.currentThread().getName();
23 | for (int i = 0; i < 10; i++) {
24 | System.out.printf("%s: %d\n", name, ThreadLocalRandom.current().nextInt(10));
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/06-08-使用原子变量/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Account;
4 | import com.concurrency.task.Bank;
5 | import com.concurrency.task.Company;
6 |
7 | public class Main {
8 | public static void main(String[] args) {
9 | // 创建一个帐户对象
10 | Account account = new Account();
11 | // 初始化帐户余额
12 | account.setBalance(1000);
13 |
14 | // 创建一个公司对象,并且将公司对象放到线程中去运行
15 | Company company = new Company(account);
16 | Thread companyThread = new Thread(company);
17 | // 创建一个银行对象,并且将银行对象放到线程中去运行
18 | Bank bank = new Bank(account);
19 | Thread bankThread = new Thread(bank);
20 |
21 | // 输出帐户对象最初的信息
22 | System.out.printf("Account : Initial Balance: %d\n", account.getBalance());
23 |
24 | // 启动线程
25 | companyThread.start();
26 | bankThread.start();
27 |
28 | try {
29 | // 等待线程完成
30 | companyThread.join();
31 | bankThread.join();
32 | // 输出余额
33 | System.out.printf("Account : Final Balance: %d\n", account.getBalance());
34 | } catch (InterruptedException e) {
35 | e.printStackTrace();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/06-08-使用原子变量/src/com/concurrency/task/Account.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.atomic.AtomicLong;
4 |
5 | /**
6 | * 帐户类
7 | */
8 | public class Account {
9 |
10 | /**
11 | * 帐户余额
12 | */
13 | private AtomicLong balance;
14 |
15 | public Account() {
16 | balance = new AtomicLong();
17 | }
18 |
19 | /**
20 | */
21 | /**
22 | * 获取帐户余额
23 | *
24 | * @return 帐户余额
25 | */
26 | public long getBalance() {
27 | return balance.get();
28 | }
29 |
30 | /**
31 | * 设置帐户余额
32 | *
33 | * @param balance 帐户余额
34 | */
35 | public void setBalance(long balance) {
36 | this.balance.set(balance);
37 | }
38 |
39 | /**
40 | * 增加余额
41 | *
42 | * @param amount 增加的数目
43 | */
44 | public void addAmount(long amount) {
45 | this.balance.getAndAdd(amount);
46 | }
47 |
48 | /**
49 | * 减少余额
50 | *
51 | * @param amount 减少的数目
52 | */
53 | public void subtractAmount(long amount) {
54 | this.balance.getAndAdd(-amount);
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/06-08-使用原子变量/src/com/concurrency/task/Bank.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 银行帐户类,模拟从一个帐户上取钱
5 | */
6 | public class Bank implements Runnable {
7 |
8 | /**
9 | * 帐户对象
10 | */
11 | private Account account;
12 |
13 | /**
14 | * 构造函数,初始化帐户属性
15 | *
16 | * @param account 帐户对象
17 | */
18 | public Bank(Account account) {
19 | this.account = account;
20 | }
21 |
22 |
23 | /**
24 | * 核心方法,取钱
25 | */
26 | @Override
27 | public void run() {
28 | for (int i = 0; i < 10; i++) {
29 | account.subtractAmount(1000);
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/06-08-使用原子变量/src/com/concurrency/task/Company.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | /**
4 | * 公司类,模拟向一个帐户存钱
5 | */
6 | public class Company implements Runnable {
7 |
8 | /**
9 | * 帐户对象
10 | */
11 | private Account account;
12 |
13 | /**
14 | * 构造函数,初始化帐户属性
15 | *
16 | * @param account 帐户对象
17 | */
18 | public Company(Account account) {
19 | this.account = account;
20 | }
21 |
22 | /**
23 | * 核心方法,存钱
24 | */
25 | @Override
26 | public void run() {
27 | for (int i = 0; i < 10; i++) {
28 | account.addAmount(1000);
29 | }
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/06-09-使用原子数组/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Decrementer;
4 | import com.concurrency.task.Incrementer;
5 |
6 | import java.util.concurrent.atomic.AtomicIntegerArray;
7 |
8 | public class Main {
9 | public static void main(String[] args) {
10 | // 线程个数
11 | final int THREADS = 100;
12 | // 原子数组对象,它有1000个元素
13 | AtomicIntegerArray vector = new AtomicIntegerArray(1000);
14 | // 创建一个加法器对象
15 | Incrementer incrementer = new Incrementer(vector);
16 | // 创建一个减法器对象
17 | Decrementer decrementer = new Decrementer(vector);
18 |
19 | // 创建并且执行100个加法线程和100个减法线程
20 | Thread threadIncrementer[] = new Thread[THREADS];
21 | Thread threadDecrementer[] = new Thread[THREADS];
22 | for (int i = 0; i < THREADS; i++) {
23 | threadIncrementer[i] = new Thread(incrementer);
24 | threadDecrementer[i] = new Thread(decrementer);
25 |
26 | threadIncrementer[i].start();
27 | threadDecrementer[i].start();
28 | }
29 |
30 | // 等待所有的任务完成
31 | for (int i = 0; i < THREADS; i++) {
32 | try {
33 | threadIncrementer[i].join();
34 | threadDecrementer[i].join();
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 |
40 | // 输出不为0的元素
41 | for (int i = 0; i < vector.length(); i++) {
42 | if (vector.get(i) != 0) {
43 | System.out.println("Vector[" + i + "] : " + vector.get(i));
44 | }
45 | }
46 |
47 | System.out.println("Main: End of the example");
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/06-09-使用原子数组/src/com/concurrency/task/Decrementer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.atomic.AtomicIntegerArray;
4 |
5 | /**
6 | * 减法器,将数组中的每元素减少指定个单位
7 | */
8 | public class Decrementer implements Runnable {
9 |
10 | /**
11 | * 要执行减法的数组
12 | */
13 | private AtomicIntegerArray vector;
14 |
15 | /**
16 | * 构造函数
17 | *
18 | * @param vector 要执行减法的数组
19 | */
20 | public Decrementer(AtomicIntegerArray vector) {
21 | this.vector = vector;
22 | }
23 |
24 | /**
25 | * 核心方法, 将数组中的每元素减少指定个单位
26 | */
27 | @Override
28 | public void run() {
29 | for (int i = 0; i < vector.length(); i++) {
30 | vector.getAndDecrement(i);
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/06-09-使用原子数组/src/com/concurrency/task/Incrementer.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.task;
2 |
3 | import java.util.concurrent.atomic.AtomicIntegerArray;
4 |
5 | /**
6 | * 加法器,将数组中的每元素增加指定个单位
7 | */
8 | public class Incrementer implements Runnable {
9 |
10 | /**
11 | * 要执行加法的数组
12 | */
13 | private AtomicIntegerArray vector;
14 |
15 | /**
16 | * 构造函数
17 | *
18 | * @param vector 要执行加法的数组
19 | */
20 | public Incrementer(AtomicIntegerArray vector) {
21 | this.vector = vector;
22 | }
23 |
24 | /**
25 | * 核心方法,将数组中的每元素增加指定个单位
26 | */
27 | @Override
28 | public void run() {
29 |
30 | for (int i = 0; i < vector.length(); i++) {
31 | vector.getAndIncrement(i);
32 | }
33 |
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/07-02-定制ThreadPoolExecutor类/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.executor.MyExecutor;
4 | import com.concurrency.task.SleepTwoSecondsTask;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.concurrent.ExecutionException;
9 | import java.util.concurrent.Future;
10 | import java.util.concurrent.LinkedBlockingDeque;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | public class Main {
14 | public static void main(String[] args) {
15 | // 创建一个定制的线程执行器
16 | MyExecutor myExecutor = new MyExecutor(2, 4, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque());
17 |
18 | // 创建一个队列来存存储任务的执行结果
19 | List> results = new ArrayList<>();
20 |
21 | // 创建并且提交10个任务
22 | for (int i = 0; i < 10; i++) {
23 | SleepTwoSecondsTask task = new SleepTwoSecondsTask();
24 | Future result = myExecutor.submit(task);
25 | results.add(result);
26 | }
27 |
28 | // 获取前5个的执行结果
29 | for (int i = 0; i < 5; i++) {
30 | try {
31 | String result = results.get(i).get();
32 | System.out.printf("Main: Result for Task %d : %s\n", i, result);
33 | } catch (InterruptedException | ExecutionException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 |
38 | // 关闭线执行器
39 | myExecutor.shutdown();
40 |
41 | // 获取后5个的执行结果
42 | for (int i = 5; i < 10; i++) {
43 | try {
44 | String result = results.get(i).get();
45 | System.out.printf("Main: Result for Task %d : %s\n", i, result);
46 | } catch (InterruptedException | ExecutionException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 |
51 | // 等待执行器执行完
52 | try {
53 | myExecutor.awaitTermination(1, TimeUnit.DAYS);
54 | } catch (InterruptedException e) {
55 | e.printStackTrace();
56 | }
57 |
58 | // 输出信息,表示整个程序运行结束
59 | System.out.printf("Main: End of the program.\n");
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/07-02-定制ThreadPoolExecutor类/src/com/concurrency/executor/MyExecutor.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-02-定制ThreadPoolExecutor类/src/com/concurrency/executor/MyExecutor.java
--------------------------------------------------------------------------------
/07-02-定制ThreadPoolExecutor类/src/com/concurrency/task/SleepTwoSecondsTask.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-02-定制ThreadPoolExecutor类/src/com/concurrency/task/SleepTwoSecondsTask.java
--------------------------------------------------------------------------------
/07-03-基于优先级的Executor类/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-03-基于优先级的Executor类/src/com/concurrency/core/Main.java
--------------------------------------------------------------------------------
/07-03-基于优先级的Executor类/src/com/concurrency/task/MyPriorityTask.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-03-基于优先级的Executor类/src/com/concurrency/task/MyPriorityTask.java
--------------------------------------------------------------------------------
/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/core/Main.java
--------------------------------------------------------------------------------
/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyTask.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyTask.java
--------------------------------------------------------------------------------
/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThread.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThread.java
--------------------------------------------------------------------------------
/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThreadFactory.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThreadFactory.java
--------------------------------------------------------------------------------
/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/core/Main.java
--------------------------------------------------------------------------------
/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyTask.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyTask.java
--------------------------------------------------------------------------------
/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThread.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThread.java
--------------------------------------------------------------------------------
/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThreadFactory.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThreadFactory.java
--------------------------------------------------------------------------------
/07-06-定制运行在线程池中的任务/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-06-定制运行在线程池中的任务/src/com/concurrency/core/Main.java
--------------------------------------------------------------------------------
/07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledTask.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledTask.java
--------------------------------------------------------------------------------
/07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledThreadPoolExecutor.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledThreadPoolExecutor.java
--------------------------------------------------------------------------------
/07-06-定制运行在线程池中的任务/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-06-定制运行在线程池中的任务/src/com/concurrency/task/Task.java
--------------------------------------------------------------------------------
/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/core/Main.java
--------------------------------------------------------------------------------
/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyRecursiveTask.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyRecursiveTask.java
--------------------------------------------------------------------------------
/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThread.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThread.java
--------------------------------------------------------------------------------
/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThreadFactory.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThreadFactory.java
--------------------------------------------------------------------------------
/07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/core/Main.java
--------------------------------------------------------------------------------
/07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/MyWorkerTask.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/MyWorkerTask.java
--------------------------------------------------------------------------------
/07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/Task.java
--------------------------------------------------------------------------------
/07-09-现实定制Lock类/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-09-现实定制Lock类/src/com/concurrency/core/Main.java
--------------------------------------------------------------------------------
/07-09-现实定制Lock类/src/com/concurrency/task/MyAbstractQueuedSynchronizer.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-09-现实定制Lock类/src/com/concurrency/task/MyAbstractQueuedSynchronizer.java
--------------------------------------------------------------------------------
/07-09-现实定制Lock类/src/com/concurrency/task/MyLock.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-09-现实定制Lock类/src/com/concurrency/task/MyLock.java
--------------------------------------------------------------------------------
/07-09-现实定制Lock类/src/com/concurrency/task/Task.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-09-现实定制Lock类/src/com/concurrency/task/Task.java
--------------------------------------------------------------------------------
/07-10-实现基于优先级的传输队列/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
1 | package com.concurrency.core;
2 |
3 | import com.concurrency.task.Consumer;
4 | import com.concurrency.task.Event;
5 | import com.concurrency.task.MyPriorityTransferQueue;
6 | import com.concurrency.task.Producer;
7 |
8 | import java.util.concurrent.TimeUnit;
9 |
10 |
11 | public class Main {
12 |
13 | public static void main(String[] args) throws Exception {
14 |
15 | MyPriorityTransferQueue buffer = new MyPriorityTransferQueue<>();
16 | Producer producer = new Producer(buffer);
17 |
18 | Thread producerThreads[] = new Thread[10];
19 | for (int i = 0; i < producerThreads.length; i++) {
20 | producerThreads[i] = new Thread(producer);
21 | producerThreads[i].start();
22 | }
23 |
24 | Consumer consumer = new Consumer(buffer);
25 | Thread consumerThread = new Thread(consumer);
26 | consumerThread.start();
27 |
28 | System.out.printf("Main: Buffer: Consumer count: %d\n", buffer.getWaitingConsumerCount());
29 |
30 |
31 | Event myEvent = new Event("Core Event", 0);
32 | buffer.transfer(myEvent);
33 | System.out.printf("Main: My Event has ben transfered.\n");
34 |
35 |
36 | for (int i = 0; i < producerThreads.length; i++) {
37 | producerThreads[i].join();
38 | }
39 |
40 | TimeUnit.SECONDS.sleep(1);
41 |
42 | System.out.printf("Main: Buffer: Consumer count: %d\n", buffer.getWaitingConsumerCount());
43 |
44 | myEvent = new Event("Core Event 2", 0);
45 | buffer.transfer(myEvent);
46 |
47 | consumerThread.join();
48 |
49 | System.out.printf("Main: End of the program\n");
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/07-10-实现基于优先级的传输队列/src/com/concurrency/task/Consumer.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-10-实现基于优先级的传输队列/src/com/concurrency/task/Consumer.java
--------------------------------------------------------------------------------
/07-10-实现基于优先级的传输队列/src/com/concurrency/task/Event.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-10-实现基于优先级的传输队列/src/com/concurrency/task/Event.java
--------------------------------------------------------------------------------
/07-10-实现基于优先级的传输队列/src/com/concurrency/task/MyPriorityTransferQueue.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-10-实现基于优先级的传输队列/src/com/concurrency/task/MyPriorityTransferQueue.java
--------------------------------------------------------------------------------
/07-10-实现基于优先级的传输队列/src/com/concurrency/task/Producer.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-10-实现基于优先级的传输队列/src/com/concurrency/task/Producer.java
--------------------------------------------------------------------------------
/07-11-实现自己的原子对象/src/com/concurrency/core/Main.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-11-实现自己的原子对象/src/com/concurrency/core/Main.java
--------------------------------------------------------------------------------
/07-11-实现自己的原子对象/src/com/concurrency/task/ParkingCounter.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-11-实现自己的原子对象/src/com/concurrency/task/ParkingCounter.java
--------------------------------------------------------------------------------
/07-11-实现自己的原子对象/src/com/concurrency/task/Sensor1.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-11-实现自己的原子对象/src/com/concurrency/task/Sensor1.java
--------------------------------------------------------------------------------
/07-11-实现自己的原子对象/src/com/concurrency/task/Sensor2.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-11-实现自己的原子对象/src/com/concurrency/task/Sensor2.java
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # java 7 并发编程实战手册
2 |
--------------------------------------------------------------------------------