Repository: Wang-Jun-Chao/java-concurrency
Branch: master
Commit: 80f41b043fd8
Files: 271
Total size: 974.4 KB
Directory structure:
gitextract_yapqjxir/
├── .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
================================================
FILE CONTENTS
================================================
================================================
FILE: .idea/.name
================================================
JAVA7并发编程实战手册
================================================
FILE: .idea/codeStyleSettings.xml
================================================
================================================
FILE: .idea/compiler.xml
================================================
================================================
FILE: .idea/copyright/profiles_settings.xml
================================================
================================================
FILE: .idea/encodings.xml
================================================
================================================
FILE: .idea/findbugs-idea.xml
================================================
================================================
FILE: .idea/misc.xml
================================================
================================================
FILE: .idea/modules.xml
================================================
================================================
FILE: .idea/scopes/scope_settings.xml
================================================
================================================
FILE: .idea/uiDesigner.xml
================================================
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
================================================
FILE: .idea/vcs.xml
================================================
================================================
FILE: 01-02-线程的创建和运行/01-02-线程的创建和运行.iml
================================================
================================================
FILE: 01-02-线程的创建和运行/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Calculator;
public class Main {
public static void main(String[] args) {
// 创建一个执行10次的循环。在每次循环中创建一个Calculator 对象,
// 一个Thread对象,这个Thread对象使用刚创建的Calculator对象作为构造器的参数,
// 然后调用刚创建的Thread对象的start()方法。
for (int i = 0; i <= 10; i++) {
Calculator calculator = new Calculator(i);
Thread thread = new Thread(calculator);
thread.start();
}
}
}
================================================
FILE: 01-02-线程的创建和运行/src/com/concurrency/task/Calculator.java
================================================
package com.concurrency.task;
// 创建一个名为Calculator的类,它实现了 Runnable接口
public class Calculator implements Runnable {
// 声明一个名为number的私有(private) int属性
private int number;
// 编写这个类的一个构造器,用来为属性number设置值。
public Calculator(int number) {
this.number = number;
}
// run方法。这个方法用来执行我们创建的线程的指令,它将对指定的数字进行乘法表运算。
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(), number, i, number * i);
}
}
}
================================================
FILE: 01-03-线程信息的获取和设置/01-03-线程信息的获取和设置.iml
================================================
================================================
FILE: 01-03-线程信息的获取和设置/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Calculator;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
public class Main {
public static void main(String[] args) {
// 线程优先级信息
System.out.printf("Minimum Priority: %s\n", Thread.MIN_PRIORITY);
System.out.printf("Normal Priority: %s\n", Thread.NORM_PRIORITY);
System.out.printf("Maximum Priority: %s\n", Thread.MAX_PRIORITY);
Thread threads[];
Thread.State status[];
// 运行10个线程,5个线程的使用最高优先级,5个线程使用最低优先级
threads = new Thread[10];
status = new Thread.State[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(new Calculator(i));
if (i % 2 == 0) {
threads[i].setPriority(Thread.MAX_PRIORITY);
} else {
threads[i].setPriority(Thread.MIN_PRIORITY);
}
threads[i].setName("Thread " + i);
}
// 等待线程完成,同时将线程状态信息写入到文件中
PrintWriter pw = null;
try {
// 获取项目运行的根路径
String configFile = Main.class.getClassLoader().getResource("").getPath();
configFile = URLDecoder.decode(configFile, "utf-8");
System.out.println(configFile);
File logFile = new File(configFile + "/data/log.txt"); // 创建一个记录文件对象
if(!logFile.getParentFile().exists()) { // 如果目录不存在就创建目录
logFile.getParentFile().mkdirs();
}
if (!logFile.exists()) { //如果文件不存在就创建一个文件
logFile.createNewFile();
}
FileWriter file = new FileWriter(logFile);
pw = new PrintWriter(file);
for (int i = 0; i < 10; i++) {
pw.println("Main : Status of Thread " + i + " : " + threads[i].getState());
status[i] = threads[i].getState();
}
for (int i = 0; i < 10; i++) {
threads[i].start();
}
boolean finish = false;
while (!finish) {
for (int i = 0; i < 10; i++) {
if (threads[i].getState() != status[i]) { // 如果线程状态发生了变化
writeThreadInfo(pw, threads[i], status[i]); // 将线程变化之前的状态写入文件
status[i] = threads[i].getState(); // 记录新的状态
}
}
finish = true;
for (int i = 0; i < 10; i++) {
// 如果所有线程都终止了finish就为true
finish = finish && (threads[i].getState() == Thread.State.TERMINATED);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (pw != null) {
pw.close();
}
}
}
/**
* 将线程状态信息写入到一个文件中
*
* @param pw 写数据的流
* @param thread 信息要被写入文件的线程
* @param state 线程的前一个状态
*/
private static void writeThreadInfo(PrintWriter pw, Thread thread, Thread.State state) {
pw.printf("Main : Id %d ---- %s\n", thread.getId(), thread.getName());
pw.printf("Main : Priority: %d\n", thread.getPriority());
pw.printf("Main : Old State: %s\n", state);
pw.printf("Main : New State: %s\n", thread.getState());
pw.printf("Main : ************************************\n");
}
}
================================================
FILE: 01-03-线程信息的获取和设置/src/com/concurrency/task/Calculator.java
================================================
package com.concurrency.task;
public class Calculator implements Runnable{
private int number;
public Calculator(int number) {
this.number = number;
}
@Override
public void run() {
// 指定的数字进行乘法表运算。
for (int i = 1; i <= 10; i++) {
System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(), number, i, number * i);
}
}
}
================================================
FILE: 01-04-线程的中断/01-04-线程的中断.iml
================================================
================================================
FILE: 01-04-线程的中断/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.PrimeGenerator;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
Thread task = new PrimeGenerator();
task.start(); // 启动质数生成线程
try {
TimeUnit.SECONDS.sleep(5); // 主线程休眠5s
} catch (InterruptedException e) {
e.printStackTrace();
}
task.interrupt(); // 质数生成线程中断
}
}
================================================
FILE: 01-04-线程的中断/src/com/concurrency/task/PrimeGenerator.java
================================================
package com.concurrency.task;
public class PrimeGenerator extends Thread {
@Override
public void run() {
long number = 1L;
while (true) {
// 对每个数字,计算它是不是一个质数,如果是的话就打印到控制台。
if (isPrime(number)) {
System.out.printf("Number %d is Prime\n", number);
}
// 当被中断时,输出一条消息,并且退出方法
if (isInterrupted()) {
System.out.printf("The Prime Generator has been Interrupted\n");
return;
}
number++;
}
}
/**
* 判断一个数是否是质数
*
* @param number 待判断的数
* @return true是质数,false不是质数
*/
private boolean isPrime(long number) {
if (number <= 2) {
return true;
}
for (long i = 2; i < number; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
================================================
FILE: 01-05-线程中断的控制/01-05-线程中断的控制.iml
================================================
================================================
FILE: 01-05-线程中断的控制/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.FileSearch;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建一个运行对象和一个运行它的线程
FileSearch searcher = new FileSearch("C:/", "readme.txt");
Thread thread = new Thread(searcher);
thread.start(); // 启动线程
try {
TimeUnit.SECONDS.sleep(10); // 主线程休眠10s
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt(); // 中断线程
}
}
================================================
FILE: 01-05-线程中断的控制/src/com/concurrency/task/FileSearch.java
================================================
package com.concurrency.task;
import java.io.File;
// 文件搜索类,给定一个文件目录,搜索其中指定的文件
public class FileSearch implements Runnable {
/**
* 搜索的初始路径
*/
private String initPath;
/**
* 要搜索的文件名
*/
private String fileName;
/**
* 构造函数
*
* @param initPath 搜索的初始路径
* @param fileName 要搜索的文件名
*/
public FileSearch(String initPath, String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
@Override
public void run() {
}
/**
* 清空资源,在本例中为空
*/
private void cleanResources() {
// 不需要做什么
}
/**
* 处理目录
*
* @param file 待处理的目录
* @throws InterruptedException 线程被中断时抛出异常
*/
private void directoryProcess(File file) throws InterruptedException {
File[] list = file.listFiles(); // 获取当目录中的所有文件
if (list != null) { // 如果当前目录下有文件
for (int i = 0; i < list.length; i++) { // 遍布所有文件
if (list[i].isDirectory()) { // 如果是一个目录
directoryProcess(list[i]); // 递归处理
} else {
fileProcess(list[i]); // 如果是一个文件,调用文件处理方法
}
}
}
}
/**
* 文件处理方法
*
* @param file 待处理的文件名
* @throws InterruptedException 线程被中断时抛出异常
*/
private void fileProcess(File file) throws InterruptedException {
if (file.getName().equals(this.fileName)) { // 当前文件名与要查找的文件同名,就输出信息
System.out.printf("%s : %s\n", Thread.currentThread().getName(), file.getAbsolutePath());
}
if (Thread.interrupted()) { // 程序被中断就抛出异常
throw new InterruptedException();
}
}
}
================================================
FILE: 01-06-线程的休眠和恢复/01-06-线程的休眠和恢复.iml
================================================
================================================
FILE: 01-06-线程的休眠和恢复/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.FileClock;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建一个文件时间运行对象,并且将其放入一个线程对象中
FileClock clock = new FileClock();
Thread thread = new Thread(clock);
// 开始线程
thread.start();
try {
// 等待五秒
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 中断线程
thread.interrupt();
}
}
================================================
FILE: 01-06-线程的休眠和恢复/src/com/concurrency/task/FileClock.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.TimeUnit;
// 文件定时类,每隔一秒钟将实际的时间输出
public class FileClock implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.printf("%s\n", new Date());
try {
// 休眠一秒
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// 当线程被中断时,释放或者关闭线程正在使用的资源。
System.out.printf("The FileClock has been interrupted");
return; // 发生异常就跳出
}
}
}
}
================================================
FILE: 01-07-等待线程的终止/01-07-等待线程的终止.iml
================================================
================================================
FILE: 01-07-等待线程的终止/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.DataSourcesLoader;
import com.concurrency.task.NetworkConnectionsLoader;
import java.util.Date;
public class Main {
public static void main(String[] args) {
// 创建并启动数据源加载器
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = new Thread(dsLoader, "DataSourceThread");
thread1.start();
// 创建并且启动网络连接加载器
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = new Thread(ncLoader, "NetworkConnectionLoader");
thread2.start();
// 待待两个线程的任务完成
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 两个任务都完成后输出一条消息
System.out.printf("Main: Configuration has been loaded: %s\n", new Date());
}
}
================================================
FILE: 01-07-等待线程的终止/src/com/concurrency/task/DataSourcesLoader.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* 数据源加载器,模拟数据加载,它会休眠10s
*/
public class DataSourcesLoader implements Runnable {
@Override
public void run() {
// 输出一条消息
System.out.printf("Beginning data sources loading: %s\n",new Date());
// 休眠10s
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出一条消息
System.out.printf("Data sources loading has finished: %s\n",new Date());
}
}
================================================
FILE: 01-07-等待线程的终止/src/com/concurrency/task/NetworkConnectionsLoader.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* 网络连接加载器,模拟网络连接,它会休眠6s
*/
public class NetworkConnectionsLoader implements Runnable {
@Override
public void run() {
// 输出一条消息
System.out.printf("Begining network connections loading: %s\n",new Date());
// 休眠6s
try {
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出一条消息
System.out.printf("Network connections loading has finished: %s\n",new Date());
}
}
================================================
FILE: 01-08-守护线程的创建和运行/01-08-守护线程的创建和运行.iml
================================================
================================================
FILE: 01-08-守护线程的创建和运行/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.event.Event;
import com.concurrency.task.CleanerTask;
import com.concurrency.task.WriterTask;
import java.util.ArrayDeque;
import java.util.Deque;
public class Main {
public static void main(String[] args) {
// 创建一个用于存放事件对象的队列
Deque deque = new ArrayDeque();
// 创建一个写任务的对象,并且创建三个线程去调用这个对象
WriterTask writer = new WriterTask(deque);
for (int i = 0; i < 3; i++) {
Thread thread = new Thread(writer);
thread.start();
}
// 创建一个事件清除任务,并且启动这个任务
CleanerTask cleaner = new CleanerTask(deque);
cleaner.start();
}
}
================================================
FILE: 01-08-守护线程的创建和运行/src/com/concurrency/event/Event.java
================================================
package com.concurrency.event;
import java.util.Date;
/**
* 事件类,存储事件信息
*/
public class Event {
/**
* 事件日期
*/
private Date date;
/**
* 事件信息
*/
private String event;
/**
* 获取事件日期
*
* @return 事件日期
*/
public Date getDate() {
return date;
}
/**
* 设置事件日期
*
* @param date 事件日期
*/
public void setDate(Date date) {
this.date = date;
}
/**
* 获取事件信息
*
* @return 事件信息
*/
public String getEvent() {
return event;
}
/**
* 设置事件信息
*
* @param event 事件信息
*/
public void setEvent(String event) {
this.event = event;
}
}
================================================
FILE: 01-08-守护线程的创建和运行/src/com/concurrency/task/CleanerTask.java
================================================
package com.concurrency.task;
import com.concurrency.event.Event;
import java.util.Date;
import java.util.Deque;
/**
* 事件清除类,每隔10秒从队尾取出一个事件,并且删除这个事件
*/
public class CleanerTask extends Thread {
/**
* 用于存储事件对象的队列
*/
Deque deque;
/**
* 构造函数
*
* @param deque 存储事件对象的队列
*/
public CleanerTask(Deque deque) {
this.deque = deque;
setDaemon(true); // 表明当前对象是一个精灵线程
}
@Override
public void run() {
while (true) {
Date date = new Date();
clean(date);
}
}
/**
* 清除方法,生存时间长于10秒的事件进行清除
* @param date 当前时间
*/
private void clean(Date date) {
long difference;
boolean delete;
if (this.deque.size() == 0) {
return;
}
delete = false;
do {
Event e = this.deque.getLast();
difference = date.getTime() - e.getDate().getTime(); // 计算最早的事件距离现在的时间
if (difference > 10000) { // 大于10秒就输出信息,并且删除最先发生的事件
System.out.printf("Cleaner: %s\n", e.getEvent());
deque.removeLast();
delete = true;
}
} while (difference > 10000);
if (delete) { // 有删除就输出删除后队列的大小
System.out.printf("Cleaner: Size of the queue: %d\n", deque.size());
}
}
}
================================================
FILE: 01-08-守护线程的创建和运行/src/com/concurrency/task/WriterTask.java
================================================
package com.concurrency.task;
import com.concurrency.event.Event;
import java.util.Date;
import java.util.Deque;
import java.util.concurrent.TimeUnit;
/**
* 写事件的类,每一秒钟产生一个事件对象
*/
public class WriterTask implements Runnable {
/**
* 用于存储事件对象的队列
*/
Deque deque;
/**
* 构造函数
*
* @param deque 存储事件对象的队列
*/
public WriterTask(Deque deque) {
this.deque = deque;
}
@Override
public void run() {
// 产生100个事件对象
for (int i = 1; i < 100; i++) {
// 创建和初始化事件对象
Event event = new Event();
event.setDate(new Date());
event.setEvent(String.format("The thread %s has generated an event", Thread.currentThread().getId()));
// 将事件添加对队列头部
deque.addFirst(event);
try {
// 休眠一秒种
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
================================================
FILE: 01-09-线程中不可控异常的处理/01-09-线程中不可控异常的处理.iml
================================================
================================================
FILE: 01-09-线程中不可控异常的处理/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.handler.ExceptionHandler;
import com.concurrency.task.Task;
public class Main {
public static void main(String[] args) {
Task task = new Task(); // 创建一个任务
Thread thread = new Thread(task); // 创建一个线程
thread.setUncaughtExceptionHandler(new ExceptionHandler()); // 设置线程的异常处理器
thread.start();
try {
thread.join(); // 等待线程完成
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Thread has finished\n");
}
}
================================================
FILE: 01-09-线程中不可控异常的处理/src/com/concurrency/handler/ExceptionHandler.java
================================================
package com.concurrency.handler;
/**
* 异常处理类,处理线程中抛出的未捕获的异常
*/
public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
/**
* 处理线程中抛出的未捕获的异常
* @param t 招聘异常的线程
* @param e 抛出的异常
*/
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("An exception has been captured\n");
System.out.printf("Thread: %s\n", t.getId());
System.out.printf("Exception: %s: %s\n", e.getClass().getName(), e.getMessage());
System.out.printf("Stack Trace: \n");
e.printStackTrace(System.out);
System.out.printf("Thread status: %s\n", t.getState());
}
}
================================================
FILE: 01-09-线程中不可控异常的处理/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
/**
* 任务类,专门抛出异常
*/
public class Task implements Runnable {
@Override
public void run() {
// 下面的语句会招聘异常
int number = Integer.parseInt("TTT");
}
}
================================================
FILE: 01-10-线程局部变量的使用/01-10-线程局部变量的使用.iml
================================================
================================================
FILE: 01-10-线程局部变量的使用/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.UnsafeTask;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建线程不安全的任务
UnsafeTask task = new UnsafeTask();
// 将任务入进三个不同的线程中
for (int i = 0; i < 3; i++) {
Thread thread = new Thread(task);
thread.start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
================================================
FILE: 01-10-线程局部变量的使用/src/com/concurrency/core/SafeMain.java
================================================
package com.concurrency.core;
import com.concurrency.task.SafeTask;
import java.util.concurrent.TimeUnit;
public class SafeMain {
public static void main(String[] args) {
// 创建一个任务
SafeTask task = new SafeTask();
// 将任务放入三个不同的线程中运行
for (int i = 0; i < 3; i++) {
Thread thread = new Thread(task);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.start();
}
}
}
================================================
FILE: 01-10-线程局部变量的使用/src/com/concurrency/task/SafeTask.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class SafeTask implements Runnable {
/**
* 线程局部变量,其中的内容不能共享,线程被初始化时会创建其包含的变量
*/
private static ThreadLocal startDate = new ThreadLocal() {
@Override
protected Date initialValue() {
return new Date();
}
};
@Override
public void run() {
System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread().getId(), startDate.get());
try {
TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread().getId(), startDate.get());
}
}
================================================
FILE: 01-10-线程局部变量的使用/src/com/concurrency/task/UnsafeTask.java
================================================
package com.concurrency.task;
import java.sql.Time;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* 线程不安全的任务,当这个任务在多个线程中时,其中的变量会被多个线程其享
*/
public class UnsafeTask implements Runnable {
/**
* 日期对象,被所有线程共享
*/
private Date startDate;
@Override
public void run() {
this.startDate = new Date();
System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread().getId(), startDate);
try {
TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread().getId(), startDate);
}
}
================================================
FILE: 01-11-线程分组/01-11-线程分组.iml
================================================
================================================
FILE: 01-11-线程分组/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Result;
import com.concurrency.task.SearchTask;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建一个线程组
ThreadGroup threadGroup = new ThreadGroup("Searcher");
// 创建一个结果对象
Result result = new Result();
// 创建一个搜索任务,并且创建5个线程去运行这个任务
SearchTask searchTask = new SearchTask(result);
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(threadGroup, searchTask);
thread.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 输出线程组的信息
System.out.printf("Number of Threads: %d\n", threadGroup.activeCount());
System.out.printf("Information about the Thread Group\n");
threadGroup.list(); // 将有关此线程组的信息打印到标准输出。
Thread[] threads = new Thread[threadGroup.activeCount()]; // 返回此线程组中活动线程的估计数。
threadGroup.enumerate(threads); // 把此线程组及其子组中的所有活动线程复制到指定数组中。
for (int i = 0; i < threadGroup.activeCount(); i++) {
System.out.printf("Thread %s: %s\n", threads[i].getName(), threads[i].getState());
}
// 等待线程结束
waitFinish(threadGroup);
// 中断线程组中的所有线程
threadGroup.interrupt();
}
/**
* 等待线程组中的一个线程结束
*
* @param threadGroup 线程组
*/
private static void waitFinish(ThreadGroup threadGroup) {
while (threadGroup.activeCount() > 9) { // 如果线程组中的活动线程数大于9个,当前调用线程就休眠1秒,直到线程数小于9个
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
================================================
FILE: 01-11-线程分组/src/com/concurrency/task/Result.java
================================================
package com.concurrency.task;
/**
* 结果类用于存储搜索结果
*/
public class Result {
/**
* 完成任务的线程名
*/
private String name;
/**
* 获取完成任务的线程名
* @return 完成任务的线程名
*/
public String getName() {
return name;
}
/**
* 设置完成任务的线程名
* @param name 完成任务的线程名
*/
public void setName(String name) {
this.name = name;
}
}
================================================
FILE: 01-11-线程分组/src/com/concurrency/task/SearchTask.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class SearchTask implements Runnable {
/**
* 如果线程完成了任务,并且没有中断,就存储线程的名字。
*/
private Result result;
/**
* 构造函数
*
* @param result 结果对象
*/
public SearchTask(Result result) {
this.result = result;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.printf("Thread %s: Start\n", name);
try {
doTask();
result.setName(name);
} catch (InterruptedException e) {
System.out.printf("Thread %s: Interrupted\n", name);
return;
}
System.out.printf("Thread %s: End\n", name);
}
/**
* 模拟搜索操作
*
* @throws InterruptedException 中断异常
*/
private void doTask() throws InterruptedException {
Random random = new Random((new Date()).getTime());
int value = (int) (random.nextDouble() * 100);
System.out.printf("Thread %s: %d\n", Thread.currentThread().getName(), value);
TimeUnit.SECONDS.sleep(value);
}
}
================================================
FILE: 01-12-线程组中不可控制异常的处理/01-12-线程组中不可控制异常的处理.iml
================================================
================================================
FILE: 01-12-线程组中不可控制异常的处理/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.group.MyThreadGroup;
import com.concurrency.task.Task;
public class Main {
public static void main(String[] args) {
// 创建一个自定义的线程组
MyThreadGroup threadGroup = new MyThreadGroup("MyThreadGroup");
// 创建一个任务
Task task = new Task();
// 创建两个线程,将其放入同一个线程组中,并且执行同一个任务
for (int i = 0; i < 2; i++) {
Thread t = new Thread(threadGroup, task);
t.start();
}
}
}
================================================
FILE: 01-12-线程组中不可控制异常的处理/src/com/concurrency/group/MyThreadGroup.java
================================================
package com.concurrency.group;
public class MyThreadGroup extends ThreadGroup {
/**
* 构造函数
*
* @param name 线程组名称
*/
public MyThreadGroup(String name) {
super(name);
}
/**
* 重写未捕获的异常方法
*
* @param t 抛出异常的信息
* @param e 抛出的异常
*/
@Override
public void uncaughtException(Thread t, Throwable e) {
// 打印线程的名称
System.out.printf("The thread %s has thrown an Exception\n", t.getId());
// 输出异常栈信息
e.printStackTrace(System.out);
// 中断线程组中其余的线程
System.out.printf("Terminating the rest of the Threads\n");
interrupt();
}
}
================================================
FILE: 01-12-线程组中不可控制异常的处理/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.Random;
public class Task implements Runnable {
@Override
public void run() {
int result;
// 创建一个随机数生成器
Random random = new Random(Thread.currentThread().getId());
while (true) {
// 生成一个[0, 1000)内有随机整数,并且有1000除以这个数,求得商
result = 1000 / ((int) (random.nextDouble() * 1000));
System.out.printf("%s : %d\n", Thread.currentThread().getId(), result);
// 检测当前线程是否被中断
if (Thread.currentThread().isInterrupted()) {
System.out.printf("%d : Interrupted\n", Thread.currentThread().getId());
return;
}
}
}
}
================================================
FILE: 01-13-使用工厂类创建线程/01-13-使用工厂类创建线程.iml
================================================
================================================
FILE: 01-13-使用工厂类创建线程/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.factory.MyThreadFactory;
import com.concurrency.task.Task;
public class Main {
public static void main(String[] args) {
// 创建一个线程工厂
MyThreadFactory factory = new MyThreadFactory("MyThreadFactory");
// 创建一个任务
Task task = new Task();
Thread thread;
// 创建并且启动10个线程对象
System.out.printf("Starting the Threads\n");
for (int i = 0; i < 10; i++) {
thread = factory.newThread(task);
thread.start();
}
// 打印线程工厂的统计信息
System.out.printf("Factory stats:\n");
System.out.printf("%s\n", factory.getStats());
}
}
================================================
FILE: 01-13-使用工厂类创建线程/src/com/concurrency/factory/MyThreadFactory.java
================================================
package com.concurrency.factory;
import com.sun.javafx.beans.annotations.NonNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ThreadFactory;
public class MyThreadFactory implements ThreadFactory {
private int counter; // 线程计数器,计数已经产生了多少个线程
private String name; // 线程的基准名称
private List stats; // 线程统计信息集合
/**
* 构造函数
*
* @param name 线程对象的基准名称
*/
public MyThreadFactory(String name) {
this.name = name;
this.counter = 0;
this.stats = new ArrayList();
}
/**
* 使用Runnable对象创建一个线程
*
* @param r Runnable对象
* @return 线程对象
*/
@Override
public Thread newThread(Runnable r) {
// 创建一个新的线程对象
Thread t = new Thread(r, this.name + "-Thread_" + this.counter);
this.counter++;
// Actualize the statistics of the factory
this.stats.add(String.format("Created thread %d with name %s on %s\n", t.getId(), t.getName(), new Date()));
return t;
}
/**
* 获取线程工厂的统计信息
*
* @return 线程工厂的统计信息
*/
public String getStats() {
StringBuffer buffer = new StringBuffer();
Iterator it = stats.iterator();
while (it.hasNext()) {
buffer.append(it.next());
}
return buffer.toString();
}
}
================================================
FILE: 01-13-使用工厂类创建线程/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
public class Task implements Runnable {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 02-02-使用synchronized实现同步方法-问题/02-02-使用synchronized实现同步方法-问题.iml
================================================
================================================
FILE: 02-02-使用synchronized实现同步方法-问题/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Account;
import com.concurrency.task.Bank;
import com.concurrency.task.Company;
public class Main {
public static void main(String[] args) {
// 创建一个帐户对象
Account account = new Account();
// 帐户初始值为1000
account.setBalance(1000);
// 创建一个公司对象,并且让公司对象在一个线程中运行
Company company = new Company(account);
Thread companyThread = new Thread(company);
// 创建一个银行对象,并且让银行对象在一个线程中运行
Bank bank = new Bank(account);
Thread bankThread = new Thread(bank);
// 输出初始的余额
System.out.printf("Account : Initial Balance: %f\n", account.getBalance());
// 启动公司和银行两个线程
companyThread.start();
bankThread.start();
try {
// 等待两个线程的完成
companyThread.join();
bankThread.join();
// 输出最后的余额
System.out.printf("Account : Final Balance: %f\n", account.getBalance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 02-02-使用synchronized实现同步方法-问题/src/com/concurrency/task/Account.java
================================================
package com.concurrency.task;
/**
* 帐户类,模拟一个银行帐户
*/
public class Account {
/**
* 帐户余额
*/
private double balance;
/**
* 获取帐户余额
*
* @return 帐户余额
*/
public double getBalance() {
return balance;
}
/**
* 设置帐户余额
*
* @param balance 帐户余额
*/
public void setBalance(double balance) {
this.balance = balance;
}
/**
* 增加帐户余额
*
* @param amount 增加的余额
*/
public void addAccount(double amount) {
double tmp = balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp += amount;
balance = tmp;
}
/**
* 减少帐户余额
*
* @param amount 减少的余额
*/
public void subtractAmount(double amount) {
double tmp = balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp -= amount;
balance = tmp;
}
}
================================================
FILE: 02-02-使用synchronized实现同步方法-问题/src/com/concurrency/task/Bank.java
================================================
package com.concurrency.task;
public class Bank implements Runnable {
/**
* 一个帐户
*/
private Account account;
/**
* 构造函数
*
* @param account 银行帐户
*/
public Bank(Account account) {
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
this.account.subtractAmount(1000);
}
}
}
================================================
FILE: 02-02-使用synchronized实现同步方法-问题/src/com/concurrency/task/Company.java
================================================
package com.concurrency.task;
public class Company implements Runnable {
/**
* 一个帐户
*/
private Account account;
/**
* 构造函数
* @param account 帐户对象
*/
public Company(Account account) {
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
this.account.addAccount(1000);
}
}
}
================================================
FILE: 02-02-使用synchronized实现同步方法-问题解决/02-02-使用synchronized实现同步方法-问题解决.iml
================================================
================================================
FILE: 02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Account;
import com.concurrency.task.Bank;
import com.concurrency.task.Company;
public class Main {
public static void main(String[] args) {
// 创建一个帐户对象
Account account = new Account();
// 帐户初始值为1000
account.setBalance(1000);
// 创建一个公司对象,并且让公司对象在一个线程中运行
Company company = new Company(account);
Thread companyThread = new Thread(company);
// 创建一个银行对象,并且让银行对象在一个线程中运行
Bank bank = new Bank(account);
Thread bankThread = new Thread(bank);
// 输出初始的余额
System.out.printf("Account : Initial Balance: %f\n", account.getBalance());
// 启动公司和银行两个线程
companyThread.start();
bankThread.start();
try {
// 等待两个线程的完成
companyThread.join();
bankThread.join();
// 输出最后的余额
System.out.printf("Account : Final Balance: %f\n", account.getBalance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/task/Account.java
================================================
package com.concurrency.task;
/**
* 帐户类,模拟一个银行帐户
*/
public class Account {
/**
* 帐户余额
*/
private double balance;
/**
* 获取帐户余额
*
* @return 帐户余额
*/
public double getBalance() {
return balance;
}
/**
* 设置帐户余额
*
* @param balance 帐户余额
*/
public void setBalance(double balance) {
this.balance = balance;
}
/**
* 增加帐户余额
*
* @param amount 增加的余额
*/
public synchronized void addAccount(double amount) {
double tmp = balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp += amount;
balance = tmp;
}
/**
* 减少帐户余额
*
* @param amount 减少的余额
*/
public synchronized void subtractAmount(double amount) {
double tmp = balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp -= amount;
balance = tmp;
}
}
================================================
FILE: 02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/task/Bank.java
================================================
package com.concurrency.task;
public class Bank implements Runnable {
/**
* 一个帐户
*/
private Account account;
/**
* 构造函数
*
* @param account 银行帐户
*/
public Bank(Account account) {
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
this.account.subtractAmount(1000);
}
}
}
================================================
FILE: 02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/task/Company.java
================================================
package com.concurrency.task;
public class Company implements Runnable {
/**
* 一个帐户
*/
private Account account;
/**
* 构造函数
* @param account 帐户对象
*/
public Company(Account account) {
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
this.account.addAccount(1000);
}
}
}
================================================
FILE: 02-03-使用非依赖属性实现同步/02-03-使用非依赖属性实现同步.iml
================================================
================================================
FILE: 02-03-使用非依赖属性实现同步/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Cinema;
import com.concurrency.task.TicketOffice1;
import com.concurrency.task.TicketOffice2;
public class Main {
public static void main(String[] args) {
// 创建一个电影院对象
Cinema cinema = new Cinema();
// 创建一个出售一号影院厅票的售票窗口对象,并且让其在一个线程中运行
TicketOffice1 ticketOffice1 = new TicketOffice1(cinema);
Thread thread1 = new Thread(ticketOffice1, "TicketOffice1");
// 创建一个出售二号影院厅票的售票窗口对象,并且让其在一个线程中运行
TicketOffice2 ticketOffice2 = new TicketOffice2(cinema);
Thread thread2 = new Thread(ticketOffice2, "TicketOffice2");
// 启动两个售票窗口线程
thread1.start();
thread2.start();
try {
// 等待两个线程完成
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出电影院剩余的票数
System.out.printf("Room 1 Vacancies: %d\n", cinema.getVacanciesCinema1());
System.out.printf("Room 2 Vacancies: %d\n", cinema.getVacanciesCinema2());
}
}
================================================
FILE: 02-03-使用非依赖属性实现同步/src/com/concurrency/task/Cinema.java
================================================
package com.concurrency.task;
/**
* 影院类,其有两个影院厅
*/
public class Cinema {
/**
* 保存影院厅1的剩余电影票数
*/
private long vacanciesCinema1;
/**
* 保存影院厅2的剩余电影票数
*/
private long vacanciesCinema2;
/**
* 控制vacanciesCinema1同步访问的对象
*/
private final Object controlCinema1;
/**
* 控制 vacanciesCinema2同步访问的对象
*/
private final Object controlCinema2;
public Cinema() {
controlCinema1 = new Object(); // 初始化同步控制变量
controlCinema2 = new Object(); // 初始化同步控制变量
vacanciesCinema1 = 20; // 设置初始空闲票数
vacanciesCinema2 = 20; // 设置初始空闲票数
}
/**
* 出售影院厅1的门票
*
* @param number 出售的门票张数
* @return true出售成功,false出售失败
*/
public boolean sellTickets1(int number) {
synchronized (controlCinema1) {
if (number < vacanciesCinema1) {
vacanciesCinema1 -= number;
return true;
} else {
return false;
}
}
}
/**
* 出售影院厅2的门票
*
* @param number 出售的门票张数
* @return true出售成功,false出售失败
*/
public boolean sellTickets2(int number) {
synchronized (controlCinema2) {
if (number < vacanciesCinema2) {
vacanciesCinema2 -= number;
return true;
} else {
return false;
}
}
}
/**
* 向售影院厅1退门票
*
* @param number 退的门票张数
* @return true退票成功,总返回true
*/
public boolean returnTickets1(int number) {
synchronized (controlCinema1) {
vacanciesCinema1 += number;
return true;
}
}
/**
* 向售影院厅2退门票
*
* @param number 退的门票张数
* @return true退票成功,总返回true
*/
public boolean returnTickets2(int number) {
synchronized (controlCinema2) {
vacanciesCinema2 += number;
return true;
}
}
/**
* 获取影院厅1剩余的门票数
*
* @return 影院1剩余的门票数
*/
public long getVacanciesCinema1() {
return vacanciesCinema1;
}
/**
* 获取影院厅2剩余的门票数
*
* @return 影院2剩余的门票数
*/
public long getVacanciesCinema2() {
return vacanciesCinema2;
}
}
================================================
FILE: 02-03-使用非依赖属性实现同步/src/com/concurrency/task/TicketOffice1.java
================================================
package com.concurrency.task;
/**
* 售票窗口类,出售1号放映厅的票
*/
public class TicketOffice1 implements Runnable {
/**
* 电影院对象
*/
private Cinema cinema;
/**
* 构造函数
* @param cinema 电影院对象
*/
public TicketOffice1(Cinema cinema) {
this.cinema = cinema;
}
@Override
public void run() {
cinema.sellTickets1(3);
cinema.sellTickets1(2);
cinema.sellTickets2(2);
cinema.returnTickets1(3);
cinema.sellTickets1(5);
cinema.sellTickets2(2);
cinema.sellTickets2(2);
cinema.sellTickets2(2);
}
}
================================================
FILE: 02-03-使用非依赖属性实现同步/src/com/concurrency/task/TicketOffice2.java
================================================
package com.concurrency.task;
/**
* 售票窗口类,出售2号放映厅的票
*/
public class TicketOffice2 implements Runnable {
/**
* 电影院对象
*/
private Cinema cinema;
/**
* 构造函数
*
* @param cinema 电影院对象
*/
public TicketOffice2(Cinema cinema) {
this.cinema = cinema;
}
@Override
public void run() {
cinema.sellTickets2(2);
cinema.sellTickets2(4);
cinema.sellTickets1(2);
cinema.sellTickets1(1);
cinema.returnTickets2(2);
cinema.sellTickets1(3);
cinema.sellTickets2(2);
cinema.sellTickets1(2);
}
}
================================================
FILE: 02-04-在同步代码中使用条件/02-04-在同步代码中使用条件.iml
================================================
================================================
FILE: 02-04-在同步代码中使用条件/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Consumer;
import com.concurrency.task.EventStorage;
import com.concurrency.task.Producer;
public class Main {
public static void main(String[] args) {
// 创建一个事件存储对象
EventStorage storage = new EventStorage();
// 创建一个事件生产者对象,并且将其放入到一个线程中运行
Producer producer = new Producer(storage);
Thread thread1 = new Thread(producer);
// 创建一个事件消费者对象,并且将其放入到一个线程中运行
Consumer consumer = new Consumer(storage);
Thread thread2 = new Thread(consumer);
// 启动两线程
thread2.start();
thread1.start();
}
}
================================================
FILE: 02-04-在同步代码中使用条件/src/com/concurrency/task/Consumer.java
================================================
package com.concurrency.task;
/**
* 消费者对象,消费事件
*/
public class Consumer implements Runnable {
/**
* 事件存储对象
*/
private EventStorage storage;
/**
* 构造函数
*
* @param storage 事件存储对象
*/
public Consumer(EventStorage storage) {
this.storage = storage;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
this.storage.get(); // 消费事件
}
}
}
================================================
FILE: 02-04-在同步代码中使用条件/src/com/concurrency/task/EventStorage.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
* 事件存储类,生产者会存储事件,消费者会处理存储的事件,一个事件就是一个日期对象
*/
public class EventStorage {
/**
* 最多可以保存的事件数
*/
private int maxSize;
/**
* 存储事件的集合
*/
private List storage;
/**
* 构造函数
*/
public EventStorage() {
this.maxSize = 10; // 最多可以存储10个事件
this.storage = new LinkedList(); // 初始化事件存储集合
}
/**
* 同步方法,向事件集合中添加一个事件
*/
public synchronized void set() {
while (this.storage.size() == this.maxSize) { // 如果集合已经满了,就等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.storage.add(new Date()); // 产生事件
System.out.printf("Set: %d\n", storage.size());
notify(); // 唤醒其它线程
}
/**
* 同步方法,使用处理事件集合中的一个事件
*/
public synchronized void get() {
while (this.storage.size() == 0) { // 如果集合为空就等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("Get: %d: %s\n", storage.size(), ((LinkedList>) storage).poll()); // 消费一个事件
notify(); // 唤醒其它线程
}
}
================================================
FILE: 02-04-在同步代码中使用条件/src/com/concurrency/task/Producer.java
================================================
package com.concurrency.task;
/**
* 生产者对象,生产事件
*/
public class Producer implements Runnable {
/**
* 事件存储对象
*/
private EventStorage storage;
/**
* 构造函数
*
* @param storage 事件存储对象
*/
public Producer(EventStorage storage) {
this.storage = storage;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
this.storage.set(); // 产生事件
}
}
}
================================================
FILE: 02-05-用锁实现同步/02-05-用锁实现同步.iml
================================================
================================================
FILE: 02-05-用锁实现同步/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Job;
import com.concurrency.task.PrintQueue;
public class Main {
public static void main(String[] args) {
// 创建一个打印队列
PrintQueue printQueue = new PrintQueue();
// 创建10个打印线程
Thread thread[] = new Thread[10];
for (int i = 0; i < 10; i++) {
thread[i] = new Thread(new Job(printQueue), "Thread " + i);
}
// 启动线程
for (int i = 0; i < 10; i++) {
thread[i].start();
}
}
}
================================================
FILE: 02-05-用锁实现同步/src/com/concurrency/task/Job.java
================================================
package com.concurrency.task;
public class Job implements Runnable {
/**
* 打印文档的队列
*/
private PrintQueue printQueue;
/**
* 构造函数
*
* @param printQueue 打印文档的队列
*/
public Job(PrintQueue printQueue) {
this.printQueue = printQueue;
}
@Override
public void run() {
System.out.printf("%s: Going to print a document\n", Thread.currentThread().getName());
printQueue.printJob(new Object());
System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName());
}
}
================================================
FILE: 02-05-用锁实现同步/src/com/concurrency/task/PrintQueue.java
================================================
package com.concurrency.task;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 打印队列类,模拟一个打印队列事件
*/
public class PrintQueue {
/**
* 用于控制队列访问的锁
*/
private final Lock queueLock = new ReentrantLock();
/**
* 打印一个文档
*
* @param object 要打印的文档对象
*/
public void printJob(Object object) {
queueLock.lock(); // 上锁
try {
long duration = (long) (Math.random() * 10000);
System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000));
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock(); // 解锁
}
}
}
================================================
FILE: 02-06-使用读写锁实现同步数据访问/02-06-使用读写锁实现同步数据访问.iml
================================================
================================================
FILE: 02-06-使用读写锁实现同步数据访问/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.PricesInfo;
import com.concurrency.task.Reader;
import com.concurrency.task.Writer;
public class Main {
public static void main(String[] args) {
// 创建价格信息对象,用于存储价格
PricesInfo pricesInfo = new PricesInfo();
Reader readers[] = new Reader[5];
Thread threadsReader[] = new Thread[5];
// 创建5个读者并且将其放在不同的线程中远行
for (int i = 0; i < 5; i++) {
readers[i] = new Reader(pricesInfo);
threadsReader[i] = new Thread(readers[i]);
}
// 创建一个写者,并且将其放在一个线程中运行
Writer writer = new Writer(pricesInfo);
Thread threadWriter = new Thread(writer);
// 启动读者写者线程
for (int i = 0; i < 5; i++) {
threadsReader[i].start();
}
threadWriter.start();
}
}
================================================
FILE: 02-06-使用读写锁实现同步数据访问/src/com/concurrency/task/PricesInfo.java
================================================
package com.concurrency.task;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 价格信息类,这个类存储了两个价格,一个写者写这个价格,多个读者读这个价格
*/
public class PricesInfo {
/**
* 两个价格g
*/
private double price1;
private double price2;
/**
* 控制价格访问的锁
*/
private ReadWriteLock lock;
/**
* 构造函数,初始化价格和锁
*/
public PricesInfo() {
this.price1 = 1.0;
this.price2 = 2.0;
this.lock = new ReentrantReadWriteLock();
}
/**
* 获取第一个价格
*
* @return 第一个价格
*/
public double getPrice1() {
lock.readLock().lock();
double value = price1;
lock.readLock().unlock();
return value;
}
/**
* 获取第二个价格
*
* @return 第二个价格
*/
public double getPrice2() {
lock.readLock().lock();
double value = price2;
lock.readLock().unlock();
return value;
}
/**
* 设置两个价格
*
* @param price1 第一个价格
* @param price2 第二个价格
*/
public void setPrices(double price1, double price2) {
lock.writeLock().lock();
this.price1 = price1;
this.price2 = price2;
lock.writeLock().unlock();
}
}
================================================
FILE: 02-06-使用读写锁实现同步数据访问/src/com/concurrency/task/Reader.java
================================================
package com.concurrency.task;
/**
* 读者类,消费价格
*/
public class Reader implements Runnable {
/**
* 价格信息对象
*/
private PricesInfo pricesInfo;
/**
* 构造函数
*
* @param pricesInfo 价格信息对象
*/
public Reader(PricesInfo pricesInfo) {
this.pricesInfo = pricesInfo;
}
/**
* 核心方法,消费两个价格,并且将他们输出
*/
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.printf("%s: Price 1: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice1());
System.out.printf("%s: Price 2: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice2());
}
}
}
================================================
FILE: 02-06-使用读写锁实现同步数据访问/src/com/concurrency/task/Writer.java
================================================
package com.concurrency.task;
/**
* 写者类,产生价格
*/
public class Writer implements Runnable {
/**
* 价格信息对象
*/
private PricesInfo pricesInfo;
/**
* 构造函数
*
* @param pricesInfo 价格信息对象
*/
public Writer(PricesInfo pricesInfo) {
this.pricesInfo = pricesInfo;
}
/**
* 核心方法,写价格
*/
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.printf("Writer: Attempt to modify the prices.\n");
pricesInfo.setPrices(Math.random() * 10, Math.random() * 8);
System.out.printf("Writer: Prices have been modified.\n");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
================================================
FILE: 02-07-修改锁的公平性/02-07-修改锁的公平性.iml
================================================
================================================
FILE: 02-07-修改锁的公平性/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Job;
import com.concurrency.task.PrintQueue;
public class Main {
public static void main(String[] args) {
// 创建一个打印队列
PrintQueue printQueue = new PrintQueue();
// 创建10个打印任务并且将其放入到不同的线程中运行
Thread thread[] = new Thread[10];
for (int i = 0; i < 10; i++) {
thread[i] = new Thread(new Job(printQueue), "Thread " + i);
}
// 每隔0.1s运行一个线程,一个10个线程
for (int i = 0; i < 10; i++) {
thread[i].start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
================================================
FILE: 02-07-修改锁的公平性/src/com/concurrency/task/Job.java
================================================
package com.concurrency.task;
public class Job implements Runnable {
/**
* 打印文档的队列
*/
private PrintQueue printQueue;
/**
* 构造函数
*
* @param printQueue 打印文档的队列
*/
public Job(PrintQueue printQueue) {
this.printQueue = printQueue;
}
@Override
public void run() {
System.out.printf("%s: Going to print a document\n", Thread.currentThread().getName());
printQueue.printJob(new Object());
System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName());
}
}
================================================
FILE: 02-07-修改锁的公平性/src/com/concurrency/task/PrintQueue.java
================================================
package com.concurrency.task;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 打印队列类,模拟一个打印队列事件
*/
public class PrintQueue {
/**
* 用于控制队列访问的锁,使用公平锁
*/
private final Lock queueLock = new ReentrantLock(false);
/**
* 打印一个文档
*
* @param object 要打印的文档对象
*/
public void printJob(Object object) {
queueLock.lock(); // 上锁
try {
long duration = (long) (Math.random() * 10000);
System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000));
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock(); // 解锁
}
queueLock.lock(); // 上锁
try {
long duration = (long) (Math.random() * 10000);
System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000));
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock(); // 解锁
}
}
}
================================================
FILE: 02-08-在锁中使用多条件/02-08-在锁中使用多条件.iml
================================================
================================================
FILE: 02-08-在锁中使用多条件/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Consumer;
import com.concurrency.task.Producer;
import com.concurrency.utils.Buffer;
import com.concurrency.utils.FileMock;
public class Main {
public static void main(String[] args) {
// 创建一个文件模拟对象,它有101行
FileMock mock = new FileMock(101, 10);
// 创建一个缓冲对象,最多可以缓存20行数据
Buffer buffer = new Buffer(20);
// 创建一个生产者对象,并且让它在一个单独的线程中运行
Producer producer = new Producer(mock, buffer);
Thread threadProducer = new Thread(producer, "Producer");
// 创建三个消费者对象,并且个他们分别在不同的线程中运行
Consumer consumers[] = new Consumer[3];
Thread threadConsumers[] = new Thread[3];
for (int i = 0; i < 3; i++) {
consumers[i] = new Consumer(buffer);
threadConsumers[i] = new Thread(consumers[i], "Consumer " + i);
}
// 启动生产者和消费者线程
threadProducer.start();
for (int i = 0; i < 3; i++) {
threadConsumers[i].start();
}
}
}
================================================
FILE: 02-08-在锁中使用多条件/src/com/concurrency/task/Consumer.java
================================================
package com.concurrency.task;
import com.concurrency.utils.Buffer;
import java.util.Random;
public class Consumer implements Runnable {
/**
* 缓冲对象
*/
private Buffer buffer;
/**
* 构造函数
*
* @param buffer 缓冲对象
*/
public Consumer(Buffer buffer) {
this.buffer = buffer;
}
/**
* 核心方法,当缓冲中有数据时就进行处理
*/
@Override
public void run() {
while (buffer.hasPendingLines()) {
String line = buffer.get();
processLine(line);
}
}
/**
* 模拟处理一行数据,休眠[0,100)毫秒
*
* @param line 一行数据
*/
private void processLine(String line) {
try {
Random random = new Random();
Thread.sleep(random.nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 02-08-在锁中使用多条件/src/com/concurrency/task/Producer.java
================================================
package com.concurrency.task;
import com.concurrency.utils.Buffer;
import com.concurrency.utils.FileMock;
public class Producer implements Runnable {
/**
* 文件模拟对象
*/
private FileMock mock;
/**
* 缓冲对象
*/
private Buffer buffer;
/**
* 构造函数
*
* @param mock 文件模拟对象
* @param buffer 缓冲对象
*/
public Producer(FileMock mock, Buffer buffer) {
this.mock = mock;
this.buffer = buffer;
}
/**
* 核心方法,读取文件中的数据,并且将读取到的数据插入到缓冲区
*/
@Override
public void run() {
this.buffer.setPendingLines(true);
while (this.mock.hasMoreLines()) {
String line = this.mock.getLine();
this.buffer.insert(line);
}
this.buffer.setPendingLines(false);
}
}
================================================
FILE: 02-08-在锁中使用多条件/src/com/concurrency/utils/Buffer.java
================================================
package com.concurrency.utils;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Buffer {
/**
* 集合对象,被当作缓冲使用
*/
private LinkedList buffer;
/**
* 缓冲的最大大小
*/
private int maxSize;
/**
* 控制缓冲访问的锁
*/
private ReentrantLock lock;
/**
* 缓冲中有数据的条件
*/
private Condition lines;
/**
* 缓冲为空的条件
*/
private Condition space;
/**
* 是否追加行
*/
private boolean pendingLines;
/**
* 构造函数,初始化属性
*
* @param maxSize 缓冲最大大小
*/
public Buffer(int maxSize) {
this.maxSize = maxSize;
this.buffer = new LinkedList<>();
this.lock = new ReentrantLock();
this.lines = lock.newCondition();
this.space = lock.newCondition();
this.pendingLines = true;
}
/**
* 向缓冲区中插入一行数据
*
* @param line 一行数据
*/
public void insert(String line) {
lock.lock();
try {
while (this.buffer.size() == this.maxSize) {
this.space.await();
}
this.buffer.offer(line);
System.out.printf("%s: Inserted Line: %d\n", Thread.currentThread().getName(), this.buffer.size());
this.lines.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public String get() {
String line = null;
lock.lock();
try {
while (this.buffer.size() == 0 && hasPendingLines()) {
this.lines.await();
}
if (hasPendingLines()) {
line = this.buffer.poll();
System.out.printf("%s: Line Readed: %d\n", Thread.currentThread().getName(), this.buffer.size());
this.space.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
this.lock.unlock();
}
return line;
}
/**
* 设置是否追加行
*
* @param pendingLines true追加,false不追加
*/
public void setPendingLines(boolean pendingLines) {
this.pendingLines = pendingLines;
}
/**
* 判断是否有数据可以进行处理
*
* @return true有数据可进行处理,false无数据可以进行处理
*/
public boolean hasPendingLines() {
return this.pendingLines || this.buffer.size() > 0;
}
}
================================================
FILE: 02-08-在锁中使用多条件/src/com/concurrency/utils/FileMock.java
================================================
package com.concurrency.utils;
/**
* 文件模拟类,
*/
public class FileMock {
/**
* 模拟文件的内容
*/
private String[] content;
/**
* 当前需要处理的文件第多少行
*/
private int index;
/**
* 构造函数,随机生成文件的内容
*
* @param size 文件的行数
* @param length 每行文件的字符数
*/
public FileMock(int size, int length) {
this.content = new String[size];
for (int i = 0; i < size; i++) {
StringBuilder builder = new StringBuilder(length);
for (int j = 0; j < length; j++) {
int indice = (int) (Math.random() * 255);
builder.append((char) indice);
}
content[i] = builder.toString();
}
this.index = 0;
}
/**
* 判断是否还有文件的行数需要处理
*
* @return true是,false否
*/
public boolean hasMoreLines() {
return this.index < this.content.length;
}
/**
* 返回下一行的文件内容
*
* @return 有返回文件内容,没有返回false
*/
public String getLine() {
if (this.hasMoreLines()) {
System.out.println("Mock: " + (this.content.length - this.index));
return this.content[this.index++];
}
return null;
}
}
================================================
FILE: 02-09-应用例子/02-09-应用例子.iml
================================================
================================================
FILE: 02-09-应用例子/src/com.concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.BuildStats;
import com.concurrency.task.Sensor1;
import com.concurrency.task.Sensor2;
import java.util.Date;
/**
* Author: 王俊超
* Date: 2014-11-23
* Time: 08:38
* Declaration: All Rights Reserved !!!
*/
public class Main {
public static void main(String[] args) {
// 创建一个建筑物状态对象
BuildStats stats = new BuildStats();
// 创建场景1对象,并且让它在一个单独的线程中运行
Sensor1 sensor1 = new Sensor1(stats);
Thread thread1 = new Thread(sensor1, "Sensor 1");
// 创建场景2对象,并且让它在一个单独的线程中运行
Sensor2 sensor2 = new Sensor2(stats);
Thread thread2 = new Thread(sensor2, "Sensor 2");
// 获取实际时间
Date date1 = new Date();
// 启动线程
thread1.start();
thread2.start();
try {
// 等待线程完成
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取实际时间,并且输出实际时间
Date date2 = new Date();
stats.printStats();
System.out.println("Execution Time: " + ((date2.getTime() - date1.getTime()) / 1000));
}
}
================================================
FILE: 02-09-应用例子/src/com.concurrency/task/BuildStats.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
/**
* 建筑物状态类,对进入其中的人进行统计,并且控制建筑物中的人数
* Author: 王俊超
* Date: 2014-11-25
* Time: 07:51
* Declaration: All Rights Reserved !!!
*/
public class BuildStats {
/**
* 建筑物中的人数
*/
private long numPeople;
/**
* 模拟人进入到建筑物中
*/
public void comeIn() {
System.out.printf("%s: A person enters.\n", Thread.currentThread().getName());
synchronized (this) {
numPeople++;
}
generateCard();
}
/**
* 模拟人从建筑物中走出来
*/
public void goOut() {
System.out.printf("%s: A person leaves.\n", Thread.currentThread().getName());
synchronized (this) {
numPeople--;
}
generateReport();
}
/**
* 当人进入建筑物中时,会模拟产生一张卡
*/
private void generateCard() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 当人离开建筑物时,会模拟产生一个报告
*/
private void generateReport() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 输入建筑物中的人数
*/
public void printStats() {
System.out.printf("%d persons in the building.\n", numPeople);
}
}
================================================
FILE: 02-09-应用例子/src/com.concurrency/task/Sensor1.java
================================================
package com.concurrency.task;
/**
* Author: 王俊超
* Date: 2014-11-25
* Time: 07:59
* Declaration: All Rights Reserved !!!
*/
public class Sensor1 implements Runnable {
/**
* 建筑物状态对象
*/
private BuildStats stats;
/**
* 构造函数
*
* @param stats 建筑物状态对象
*/
public Sensor1(BuildStats stats) {
this.stats = stats;
}
/**
* 核心方法,模拟人在建筑物中的进出
*/
@Override
public void run() {
stats.comeIn();
stats.comeIn();
stats.comeIn();
stats.goOut();
stats.comeIn();
}
}
================================================
FILE: 02-09-应用例子/src/com.concurrency/task/Sensor2.java
================================================
package com.concurrency.task;
/**
* Author: 王俊超
* Date: 2014-11-25
* Time: 07:59
* Declaration: All Rights Reserved !!!
*/
public class Sensor2 implements Runnable {
/**
* 建筑物状态对象
*/
private BuildStats stats;
/**
* 构造函数
*
* @param stats 建筑物状态对象
*/
public Sensor2(BuildStats stats) {
this.stats = stats;
}
/**
* 核心方法,模拟人在建筑物中的进出
*/
@Override
public void run() {
stats.comeIn();
stats.comeIn();
stats.goOut();
stats.goOut();
stats.goOut();
}
}
================================================
FILE: 03-02-资源并发控制访问/03-02-资源并发控制访问.iml
================================================
================================================
FILE: 03-02-资源并发控制访问/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Job;
import com.concurrency.task.PrintQueue;
public class Main {
public static void main(String[] args) {
// 创建一个打印队列对象
PrintQueue printQueue = new PrintQueue();
// 创建10个线程
Thread thread[] = new Thread[10];
for (int i = 0; i < 10; i++) {
thread[i] = new Thread(new Job(printQueue), "Thread " + i);
}
// 启动10个线程
for (int i = 0; i < 10; i++) {
thread[i].start();
}
}
}
================================================
FILE: 03-02-资源并发控制访问/src/com/concurrency/task/Job.java
================================================
package com.concurrency.task;
public class Job implements Runnable {
/**
* 打印队列对象
*/
private PrintQueue printQueue;
/**
* 构造函数,初始化打印队列对象
*
* @param printQueue 打印队列对象
*/
public Job(PrintQueue printQueue) {
this.printQueue = printQueue;
}
/**
* 核心方法,向打印队列中发送打印任务,并且等待它完成
*/
@Override
public void run() {
System.out.printf("%s: Going to print a job\n", Thread.currentThread().getName());
printQueue.printJob(new Object());
System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName());
}
}
================================================
FILE: 03-02-资源并发控制访问/src/com/concurrency/task/PrintQueue.java
================================================
package com.concurrency.task;
import com.concurrency.core.Main;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* 打印队列类,使用信号量来控制打钱作业的访问
*/
public class PrintQueue {
/**
* 信号量,控制队列的访问
*/
private final Semaphore semaphore;
/**
* 构造函数,初始化信号量
*/
public PrintQueue() {
semaphore = new Semaphore(1);
}
/**
* 模拟文档打印的方法
*
* @param document 需要打印的对象
*/
public void printJob(Object document) {
try {
// 请求信号量,如果已经被其它线程请求过,则当前请求的线程会休眠,直到获得这个信号量
semaphore.acquire();
long duration = (long) (Math.random() * 10);
System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), duration);
Thread.sleep(duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放信号量,如果有其它的线程在请求这个信号量,JVN会选择其中的某一个程获取信号量,让其运行
semaphore.release();
}
}
}
================================================
FILE: 03-03-资源的多副本的并发访问控制/03-03-资源的多副本的并发访问控制.iml
================================================
================================================
FILE: 03-03-资源的多副本的并发访问控制/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Job;
import com.concurrency.task.PrintQueue;
public class Main {
public static void main(String[] args) {
// 创建一个打印对队对象
PrintQueue printQueue = new PrintQueue();
// 创建12个线程,运行作业任务,这些任务都向同一个打印队列对象发出打印请求
Thread thread[] = new Thread[12];
for (int i = 0; i < 12; i++) {
thread[i] = new Thread(new Job(printQueue), "Thread " + i);
}
// 启动12个线程
for (int i = 0; i < 12; i++) {
thread[i].start();
}
}
}
================================================
FILE: 03-03-资源的多副本的并发访问控制/src/com/concurrency/task/Job.java
================================================
package com.concurrency.task;
public class Job implements Runnable {
/**
* 打印队列对象
*/
private PrintQueue printQueue;
/**
* 构造函数,初始化打印队列对象
*
* @param printQueue 打印队列对象
*/
public Job(PrintQueue printQueue) {
this.printQueue = printQueue;
}
/**
* 核心方法,向打印队列中发送打印任务,并且等待它完成
*/
@Override
public void run() {
System.out.printf("%s: Going to print a job\n", Thread.currentThread().getName());
printQueue.printJob(new Object());
System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName());
}
}
================================================
FILE: 03-03-资源的多副本的并发访问控制/src/com/concurrency/task/PrintQueue.java
================================================
package com.concurrency.task;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 打印队列对象,它可以访问三台打印机,使用信号量来控制打印机的访问,当有一个打印作业,
* 如果有空闲的打印杨就将作业分配到某个打印机上,否则就等待打印机空闲,再分配打印机
*/
public class PrintQueue {
/**
* 资源信号量,控制打印机的访问
*/
private Semaphore semaphore;
/**
* 标记打印机是否空闲的数组
*/
private boolean[] freePrinters;
/**
* 锁,控制打印机是否空闲的数组的访问
*/
private Lock lockPrinters;
/**
* 构造函数,初始化变量
*/
public PrintQueue() {
semaphore = new Semaphore(3); // 资源信号量的个数为3,说明有3个打印机
freePrinters = new boolean[3];
for (int i = 0; i < freePrinters.length; i++) {
freePrinters[i] = true;
}
lockPrinters = new ReentrantLock();
}
/**
* 模拟文档打印的方法
*
* @param document 需要打印的对象
*/
public void printJob(Object document) {
try {
// 请求信号量,如果有一个打印机是空闲的,就会访问其中一个空闲的打印机
semaphore.acquire();
// 获取分配的打印机编号
int assignedPrinter = getPrinter();
Long duration = (long) (Math.random() * 10);
System.out.printf("%s: PrintQueue: Printing a Job in Printer %d during %d seconds\n", Thread.currentThread().getName(), assignedPrinter, duration);
TimeUnit.SECONDS.sleep(duration);
// 释放打印机
freePrinters[assignedPrinter] = true;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放信号量
semaphore.release();
}
}
/**
* 获取分配的打印机编号
* @return 分配的打印机编号
*/
private int getPrinter() {
int ret = -1;
try {
// 获取打印机状态数组的访问能力
lockPrinters.lock();
// 查找第一个空闲的打印机
for (int i = 0; i < freePrinters.length; i++) {
if (freePrinters[i]) {
ret = i;
freePrinters[i] = false;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放打印机状态数组的访问能力
lockPrinters.unlock();
}
return ret;
}
}
================================================
FILE: 03-04-等待多个并发事件的完成/03-04-等待多个并发事件的完成.iml
================================================
================================================
FILE: 03-04-等待多个并发事件的完成/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Participant;
import com.concurrency.task.VideoConference;
public class Main {
public static void main(String[] args) {
// 创建一个视频会议对象,它有10个参与者
VideoConference conference = new VideoConference(10);
// 创建一个线程去运行视频会议
Thread threadConference = new Thread(conference);
threadConference.start();
// 创建十个参与者,每个参与者在一个单独的线程中运行
for (int i = 0; i < 10; i++) {
Participant p = new Participant(conference, "Participant " + i);
Thread t = new Thread(p);
t.start();
}
}
}
================================================
FILE: 03-04-等待多个并发事件的完成/src/com/concurrency/task/Participant.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
/**
* 参与者类
*/
public class Participant implements Runnable {
/**
* 视频会议对象
*/
private VideoConference conference;
/**
* 参与者的名称(仅仅是为了记录使用)
*/
private String name;
/**
* 构造函数
*
* @param conference 视频会议对象
* @param name 参与者的名称
*/
public Participant(VideoConference conference, String name) {
this.conference = conference;
this.name = name;
}
/**
* 核心方法,等待一个随机时间就进入视频会议
*/
@Override
public void run() {
long duration = (long) (Math.random() * 10);
try {
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
conference.arrive(name);
}
}
================================================
FILE: 03-04-等待多个并发事件的完成/src/com/concurrency/task/VideoConference.java
================================================
package com.concurrency.task;
import java.util.concurrent.CountDownLatch;
/**
* 视频会类
* 使用倒计时闩来控制所有参与者都到达后才发生事件
*/
public class VideoConference implements Runnable {
/**
* 倒计时闩对象
*/
private final CountDownLatch controller;
/**
* 构造函数,初始化倒计时闩
* @param number 参与者人数
*/
public VideoConference(int number) {
controller = new CountDownLatch(number);
}
/**
* 每个参与到视频会议的都会调用此方法
* @param name 参与者
*/
public void arrive(String name) {
System.out.printf("%s has arrived.\n", name);
controller.countDown();
System.out.printf("VideoConference: Waiting for %d participants.\n", controller.getCount());
}
/**
* 核心方法,当所有参与者都到达了,就开始视频仁义
*/
@Override
public void run() {
System.out.printf("VideoConference: Initialization: %d participants.\n", controller.getCount());
try {
// Wait for all the participants
controller.await();
// Starts the conference
System.out.printf("VideoConference: All the participants have come\n");
System.out.printf("VideoConference: Let's start...\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 03-05-在集合点的同步/03-05-在集合点的同步.iml
================================================
================================================
FILE: 03-05-在集合点的同步/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Grouper;
import com.concurrency.task.Searcher;
import com.concurrency.utils.MatrixMock;
import com.concurrency.utils.Results;
import java.util.concurrent.CyclicBarrier;
public class Main {
public static void main(String[] args) {
final int ROWS = 10000; // 矩阵的行数
final int NUMBERS = 1000; // 矩阵的列数
final int SEARCH = 5; // 要查询的数字
final int PARTICIPANTS = 5; // 查询线程的个数
final int LINES_PARTICIPANT = 2000; // 每个查询线程处理的行数
MatrixMock mock = new MatrixMock(ROWS, NUMBERS, SEARCH); // 创建矩阵模拟对象
Results results = new Results(ROWS); // 创建结果对象
Grouper grouper = new Grouper(results); // 创建组合对象
// 创建一个同步栅对象,它有5个参与者, 5个参与者线程完成后,会调用grouper中的run方法
CyclicBarrier barrier = new CyclicBarrier(PARTICIPANTS, grouper);
// 创建5个参与者对象,并且让它们各自在单独的线程中运行
Searcher[] searchers = new Searcher[PARTICIPANTS];
for (int i = 0; i < searchers.length; i++) {
searchers[i] = new Searcher(barrier, i * LINES_PARTICIPANT, (i * LINES_PARTICIPANT) + LINES_PARTICIPANT,
mock, results, PARTICIPANTS);
Thread thread = new Thread(searchers[i]);
thread.start();
}
System.out.printf("Main: The main thread has finished.\n");
}
}
================================================
FILE: 03-05-在集合点的同步/src/com/concurrency/task/Grouper.java
================================================
package com.concurrency.task;
import com.concurrency.utils.Results;
/**
* 组合类,汇总查找的结果
*/
public class Grouper implements Runnable {
/**
* 结果对象
*/
private Results results;
/**
* 构造函数
*
* @param results 结果对象
*/
public Grouper(Results results) {
this.results = results;
}
/**
* 核心方法,对查找的结果进行汇总
*/
@Override
public void run() {
int finalResult = 0;
System.out.printf("Grouper: Processing results...\n");
int data[] = results.getData();
for (int number : data) {
finalResult += number;
}
System.out.printf("Grouper: Total result: %d.\n", finalResult);
}
}
================================================
FILE: 03-05-在集合点的同步/src/com/concurrency/task/Searcher.java
================================================
package com.concurrency.task;
import com.concurrency.utils.MatrixMock;
import com.concurrency.utils.Results;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* 查找类
*/
public class Searcher implements Runnable {
/**
* 开始查找的行数
*/
private int firstRow;
/**
* 最后查找的行数(不包含)
*/
private int lastRow;
/**
* 矩阵模拟对象
*/
private MatrixMock mock;
/**
* 结果对象
*/
private Results results;
/**
* 要查找的数字
*/
private int number;
/**
* 同步栅
*/
private final CyclicBarrier barrier;
/**
* 构造函数
*
* @param barrier 同步栅
* @param firstRow 开始查找的行数
* @param lastRow 最后查找的行数(不包含)
* @param mock 矩阵模拟对象
* @param results 结果对象
* @param number 要查找的数字
*/
public Searcher(CyclicBarrier barrier, int firstRow, int lastRow, MatrixMock mock, Results results, int number) {
this.barrier = barrier;
this.firstRow = firstRow;
this.lastRow = lastRow;
this.mock = mock;
this.results = results;
this.number = number;
}
/**
* 核心方法,查找指定行数范围内的指定数字,将结果保存在结果数组对应的位置
*/
@Override
public void run() {
int counter;
System.out.printf("%s: Processing lines from %d to %d.\n", Thread.currentThread().getName(), firstRow, lastRow);
for (int i = firstRow; i < lastRow; i++) {
int row[] = mock.getRow(i);
counter = 0;
for (int j = 0; j < row.length; j++) {
if (row[j] == number) {
counter++;
}
}
results.setData(i, counter);
}
System.out.printf("%s: Lines processed.\n", Thread.currentThread().getName());
try {
barrier.await(); // 等待所有查找完成
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 03-05-在集合点的同步/src/com/concurrency/utils/MatrixMock.java
================================================
package com.concurrency.utils;
import java.util.Random;
/**
* 矩阵模拟类,随机生成0-9之间数字二维矩
*/
public class MatrixMock {
/**
* 0-9之间数字二维矩阵
*/
private int[][] data;
/**
* 构造函数
*
* @param size 矩阵的行数
* @param length 每行的长度
* @param number 要查找的数字
*/
public MatrixMock(int size, int length, int number) {
int counter = 0;
data = new int[size][length];
Random random = new Random();
for (int i = 0; i < size; i++) {
for (int j = 0; j < length; j++) {
data[i][j] = random.nextInt(10);
if (data[i][j] == number) {
counter++;
}
}
}
System.out.printf("Mock: There are %d ocurrences of number in generated data.\n", counter, number);
}
/**
* 获取行row行数据
*
* @param row 行数
* @return 第row行数据,没有就返回null
*/
public int[] getRow(int row) {
if (row >= 0 && row < data.length) {
return data[row];
}
return null;
}
}
================================================
FILE: 03-05-在集合点的同步/src/com/concurrency/utils/Results.java
================================================
package com.concurrency.utils;
/**
* 结果类,保存矩阵中每行找到指定数字的次数
*/
public class Results {
/**
* 保存矩阵中每行找到指定数字的次数
*/
private int[] data;
/**
* 构造函数
*
* @param size 数组长度
*/
public Results(int size) {
this.data = new int[size];
}
/**
* 设置数组的值
*
* @param position 位置
* @param value 要设置的值
*/
public void setData(int position, int value) {
data[position] = value;
}
/**
* 获取保存的数据
*
* @return 保存的数据
*/
public int[] getData() {
return data;
}
}
================================================
FILE: 03-06-并发阶段任务的运行/03-06-并发阶段任务的运行.iml
================================================
================================================
FILE: 03-06-并发阶段任务的运行/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.FileSearch;
import java.util.concurrent.Phaser;
public class Main {
public static void main(String[] args) {
// 创建一个阶段对象,它有三个参与者
Phaser phaser = new Phaser(3);
// 创建一个文件搜索对象,每一个搜索不同的目录
FileSearch system = new FileSearch("C:\\Windows", "log", phaser);
FileSearch apps = new FileSearch("C:\\Program Files", "log", phaser);
FileSearch documents = new FileSearch("C:\\Documents And Settings", "log", phaser);
// 创建一个线程运行文件搜索对象,并且启动线程
Thread systemThread = new Thread(system, "System");
systemThread.start();
// 创建一个线程运行文件搜索对象,并且启动线程
Thread appsThread = new Thread(apps, "Apps");
appsThread.start();
// 创建一个线程运行文件搜索对象,并且启动线程
Thread documentsThread = new Thread(documents, "Documents");
documentsThread.start();
// 等待所有的线程都结束
try {
systemThread.join();
appsThread.join();
documentsThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Terminated: %s\n", phaser.isTerminated());
}
}
================================================
FILE: 03-06-并发阶段任务的运行/src/com/concurrency/task/FileSearch.java
================================================
package com.concurrency.task;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
/**
* 文件查找类,它将在一个文件夹及子文件夹中查找过去24小时内修改过的指定扩展名的文件
*/
public class FileSearch implements Runnable {
/**
* 用于查找的文件夹
*/
private String initPath;
/**
* 要查找的文件的扩展名
*/
private String end;
/**
* 查找到的文件的完整路径
*/
private List results;
/**
* 阶段对象,用来控制任务不同阶段的同步
*/
private Phaser phaser;
/**
* 构造函数,初始化声明的属性
*
* @param initPath 用于查找的文件夹
* @param end 要查找的文件的扩展名
* @param phaser 阶段对象
*/
public FileSearch(String initPath, String end, Phaser phaser) {
this.initPath = initPath;
this.end = end;
this.phaser = phaser;
this.results = new ArrayList<>();
}
/**
* 核心方法
*/
@Override
public void run() {
// 等待所有文件对象被创建
this.phaser.arriveAndAwaitAdvance();
System.out.printf("%s: Starting.\n", Thread.currentThread().getName());
// 第一个阶段:查找所有的文件
File file = new File(initPath);
if (file.isDirectory()) {
directoryProcess(file);
}
// 如果没有找到结果,就从这个阶段对象中注销,并且退出程序
if (!checkResults()) {
return;
}
// 第二阶段:过滤查找到的结果
filterResults();
// 如果过滤后没有结果,就从这个阶段对象中注销,并且退出程序
if (!checkResults()) {
return;
}
// 第三阶段:显示查找信息
showInfo();
// 通知Phaser对象,当前线程已经结束这个阶段,并且将不再参与接下来的阶段操作
phaser.arriveAndDeregister();
System.out.printf("%s: Work completed.\n", Thread.currentThread().getName());
}
/**
* 将结果集中的元素打印到控制台
*/
private void showInfo() {
for (String result : this.results) {
File file = new File(result);
System.out.printf("%s: %s\n", Thread.currentThread().getName(), file.getAbsolutePath());
}
// 通知Phaser对象,当前线程已经完成了当前阶段,需要被阻塞直到其它线程都完成当前阶段
this.phaser.arriveAndAwaitAdvance();
}
/**
* 检查结果集是否为空,如果结果集为空就从阶段对象中注销,否则等待其它的线程完成同样的的任务阶段
*
* @return false结果集为空,true结果集不为空
*/
private boolean checkResults() {
if (this.results.isEmpty()) {
System.out.printf("%s: Phase %d: 0 results.\n", Thread.currentThread().getName(), phaser.getPhase());
System.out.printf("%s: Phase %d: End.\n", Thread.currentThread().getName(), phaser.getPhase());
// 通知Phaser对象,当前线程已经结束这个阶段,并且将不再参与接下来的阶段操作
this.phaser.arriveAndDeregister();
return false;
} else {
System.out.printf("%s: Phase %d: %d results.\n", Thread.currentThread().getName(), phaser.getPhase(), results.size());
// 通知Phaser对象,当前线程已经完成了当前阶段,需要被阻塞直到其它线程都完成当前阶段
this.phaser.arriveAndAwaitAdvance();
return true;
}
}
/**
* 文件过滤方法,将不是24小时前修改过的文件删除
*/
private void filterResults() {
List newResults = new ArrayList<>();
long actualDate = new Date().getTime();
for (String result : results) {
File file = new File(result);
long fileDate = file.lastModified();
// 表明修改是在24小时前发生的
if (actualDate - fileDate < TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)) {
newResults.add(result);
}
}
results = newResults;
}
/**
* 目录处理方法,处理file目录下的所有文件夹和文件
*
* @param file 开始处理的文件
*/
private void directoryProcess(File file) {
// 获取file目录下的所有文件和目录
File list[] = file.listFiles();
if (list != null) {
for (File aFile : list) {
if (aFile.isDirectory()) {
// 如果是目录就递归处理它
directoryProcess(aFile);
} else {
// 如果是一个文件,就调用文件处理方法
fileProcess(aFile);
}
}
}
}
/**
* 文件处理方法
*
* @param file 文件对象
*/
private void fileProcess(File file) {
// 如果文件以指定的后缀点结束,就将文件的绝对路径保存到结果集合中
if (file.getName().endsWith(end)) {
results.add(file.getAbsolutePath());
}
}
}
================================================
FILE: 03-07-并发阶段任务中的阶段切换/03-07-并发阶段任务中的阶段切换.iml
================================================
================================================
FILE: 03-07-并发阶段任务中的阶段切换/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.MyPhaser;
import com.concurrency.task.Student;
public class Main {
public static void main(String[] args) {
// 创建一个阶段对象
MyPhaser phaser = new MyPhaser();
// 创建一个学生对象,将它们注册到同一个阶段对象中
Student[] students = new Student[5];
for (int i = 0; i < students.length; i++) {
students[i] = new Student(phaser);
phaser.register();
}
// 创建五个线程来运行五个学生对象,并且启动线程
Thread[] threads = new Thread[5];
for (int i = 0; i < students.length; i++) {
threads[i] = new Thread(students[i]);
threads[i].start();
}
// 等待所有线程完成执行
try {
for (int i = 0; i < threads.length; i++) {
threads[i].join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
// 检查阶段是否已经到达完成状态
System.out.printf("Main: The phaser has finished: %s.\n", phaser.isTerminated());
}
}
================================================
FILE: 03-07-并发阶段任务中的阶段切换/src/com/concurrency/task/MyPhaser.java
================================================
package com.concurrency.task;
import java.util.concurrent.Phaser;
/**
* 线程阶段类,控制线程阶段的改变
*/
public class MyPhaser extends Phaser {
/**
* @param phase 实际的阶段
* @param registeredParties 注册的线程数
* @return false表明要进一步执行,true表明已经完成
*/
@Override
protected boolean onAdvance(int phase, int registeredParties) {
switch (phase) {
case 0:
return studentArrived();
case 1:
return finishFirstExercise();
case 2:
return finishSecondExercise();
case 3:
return finishExam();
default:
return true;
}
}
/**
* 从0->1阶段改变时调用这个方法
*
* @return 总是返回false,表明还要断续执行
*/
private boolean studentArrived() {
System.out.printf("Phaser: The exam are going to start. The students are ready.\n");
System.out.printf("Phaser: We have %d students.\n", getRegisteredParties());
return false;
}
/**
* 从1->2阶段改变时调用这个方法
*
* @return 总是返回false,表明还要断续执行
*/
private boolean finishFirstExercise() {
System.out.printf("Phaser: All the students has finished the first exercise.\n");
System.out.printf("Phaser: It's turn for the second one.\n");
return false;
}
/**
* 从2->3阶段改变时调用这个方法
*
* @return 总是返回false,表明还要断续执行
*/
private boolean finishSecondExercise() {
System.out.printf("Phaser: All the students has finished the second exercise.\n");
System.out.printf("Phaser: It's turn for the third one.\n");
return false;
}
/**
* 从3->4阶段改变时调用这个方法
*
* @return 总是返回false,表明还要断续执行
*/
private boolean finishExam() {
System.out.printf("Phaser: All the students has finished the exam.\n");
System.out.printf("Phaser: Thank you for your time.\n");
return true;
}
}
================================================
FILE: 03-07-并发阶段任务中的阶段切换/src/com/concurrency/task/Student.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
/**
* 学生类
*/
public class Student implements Runnable {
/**
* 控制线程执行的阶段对象
*/
private Phaser phaser;
/**
* 构造函数
* @param phaser 控制线程招手执行的阶段对象
*/
public Student(Phaser phaser) {
this.phaser = phaser;
}
/**
* 核心方法,进入考试状态,做三个测试题,每做完一个测试题,它调用阶段对象等待所有其的学生都完成同样的测试题
*/
@Override
public void run() {
System.out.printf("%s: Has arrived to do the exam. %s\n", Thread.currentThread().getName(), new Date());
phaser.arriveAndAwaitAdvance();
System.out.printf("%s: Is going to do the first exercise. %s\n", Thread.currentThread().getName(), new Date());
doExercise1();
System.out.printf("%s: Has done the first exercise. %s\n", Thread.currentThread().getName(), new Date());
phaser.arriveAndAwaitAdvance();
System.out.printf("%s: Is going to do the second exercise. %s\n", Thread.currentThread().getName(), new Date());
doExercise2();
System.out.printf("%s: Has done the second exercise. %s\n", Thread.currentThread().getName(), new Date());
phaser.arriveAndAwaitAdvance();
System.out.printf("%s: Is going to do the third exercise. %s\n", Thread.currentThread().getName(), new Date());
doExercise3();
System.out.printf("%s: Has finished the exam. %s\n", Thread.currentThread().getName(), new Date());
phaser.arriveAndAwaitAdvance();
}
/**
* 做一个测试题,并且休眠[0, 10)秒
*/
private void doExercise1() {
try {
Long duration = (long) (Math.random() * 10);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 做一个测试题,并且休眠[0, 10)秒
*/
private void doExercise2() {
try {
Long duration = (long) (Math.random() * 10);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 做一个测试题,并且休眠[0, 10)秒
*/
private void doExercise3() {
try {
Long duration = (long) (Math.random() * 10);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 03-08-并发任务间的数据交换/03-08-并发任务间的数据交换.iml
================================================
================================================
FILE: 03-08-并发任务间的数据交换/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Consumer;
import com.concurrency.task.Producer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Exchanger;
public class Main {
public static void main(String[] args) {
// 创建两个缓存对象
List buffer1 = new ArrayList<>();
List buffer2 = new ArrayList<>();
// 创建一个交换器对象
Exchanger> exchanger = new Exchanger<>();
// 创建生产者对象
Producer producer = new Producer(exchanger, buffer1);
// 创建消费者对象
Consumer consumer = new Consumer(exchanger, buffer2);
// 创建消费者对象和生产者对象放置在不同的线程中
Thread threadProducer = new Thread(producer);
Thread threadConsumer = new Thread(consumer);
// 启动两个线程
threadProducer.start();
threadConsumer.start();
}
}
================================================
FILE: 03-08-并发任务间的数据交换/src/com/concurrency/task/Consumer.java
================================================
package com.concurrency.task;
import java.util.List;
import java.util.concurrent.Exchanger;
/**
* 消费者类
*/
public class Consumer implements Runnable {
/**
* 消费者消费数据的地方,也是与消费者交换数据的地方
*/
private List buffer;
/**
* 同步生产者与消息者交换数据的交换对象
*/
private final Exchanger> exchanger;
/**
* 构造函数,初始化属性
*
* @param exchanger 数据的交换对象
* @param buffer 数据存储对象
*/
public Consumer(Exchanger> exchanger, List buffer) {
this.exchanger = exchanger;
this.buffer = buffer;
}
/**
* 核心方法,它消费生产者产生的事件,每消费10个事件后,它使用交换对象去同步生产者。
* 它将已经消费完的空缓存对象发送给生产者,同时获取生产者生产的装有10个事件的缓存对象
*/
@Override
public void run() {
int cycle = 1;
for (int i = 0; i < 10; i++) {
System.out.printf("Consumer: Cycle %d\n", cycle);
try {
// 等待生产的数据,并且将空的缓存对象发送给生产者
buffer = exchanger.exchange(buffer);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Consumer: %d\n", buffer.size());
for (int j = 0; j < 10; j++) {
String message = buffer.get(0);
System.out.printf("Consumer: %s\n", message);
buffer.remove(0);
}
cycle++;
}
}
}
================================================
FILE: 03-08-并发任务间的数据交换/src/com/concurrency/task/Producer.java
================================================
package com.concurrency.task;
import java.util.List;
import java.util.concurrent.Exchanger;
/**
* 生产者类
*/
public class Producer implements Runnable {
/**
* 生产者生产数据后存储的地方,也是与消费者交换数据的地方
*/
private List buffer;
/**
* 同步生产者与消息者交换数据的交换对象
*/
private final Exchanger> exchanger;
/**
* 构造函数,初始化属性
*
* @param exchanger 数据的交换对象
* @param buffer 数据存储对象
*/
public Producer(Exchanger> exchanger, List buffer) {
this.exchanger = exchanger;
this.buffer = buffer;
}
/**
* 核心方法,产生100个事件,分10次产生,每次产生10个事件,每个产生10个事件后,
* 调用数据交换对象去同步消费者。生产者将存放10个事件的缓存对象发送给消费者,
* 并且从消费者那里接收到一个空的缓存对象
*/
@Override
public void run() {
int cycle = 1;
for (int i = 0; i < 10; i++) {
System.out.printf("Producer: Cycle %d\n", cycle);
// 生产10个事件
for (int j = 0; j < 10; j++) {
String message = "Event " + ((i * 10) + j);
System.out.printf("Producer: %s\n", message);
buffer.add(message);
}
try {
// 与消费者交换数据
buffer = exchanger.exchange(buffer);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Producer: %d\n", buffer.size());
cycle++;
}
}
}
================================================
FILE: 04-02-创建线程执行器/04-02-创建线程执行器.iml
================================================
================================================
FILE: 04-02-创建线程执行器/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Server;
import com.concurrency.task.Task;
public class Main {
public static void main(String[] args) {
Server server = new Server();
// 发送100个任务到服务器对象,并且完成任务
for (int i = 0; i < 100; i++) {
Task task = new Task("Task " + i);
server.executeTask(task);
}
server.endServer();
}
}
================================================
FILE: 04-02-创建线程执行器/src/com/concurrency/task/Server.java
================================================
package com.concurrency.task;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 服务类,模拟一个服务器
*/
public class Server {
/**
* 线程池执行器,管理请求线程的执行
*/
private ThreadPoolExecutor executor;
/**
* 构造函数,创建线程执行器对象
*/
public Server() {
executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); // 本质是一个缓冲线程池对象
}
/**
* 任务执行方法 接收Task对象作为参数并将其提交到执行者
*
* @param task Task对象
*/
public void executeTask(Task task) {
// 首先,写入一条信息到控制台,表明有一个新的任务到达。
System.out.printf("Server: A new task has arrived\n");
// 然后,调用执行者的execute()方法来提交这个任务
executor.execute(task);
// 最后,将执行者的数据写入到控制台来看它们的状态
System.out.printf("Server: Pool Size: %d\n", executor.getPoolSize());
System.out.printf("Server: Active Count: %d\n", executor.getActiveCount());
System.out.printf("Server: Completed Tasks: %d\n", executor.getCompletedTaskCount());
}
/**
* 结束执行的方法
*/
public void endServer() {
// 调用执行者的shutdown()方法来结束任务执行
executor.shutdown();
}
}
================================================
FILE: 04-02-创建线程执行器/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* 任务类
*/
public class Task implements Runnable {
/**
* 任务创建的时间
*/
private Date initDate;
/**
* 任务的名称
*/
private String name;
/**
* 构造函数,初始化属性
*
* @param name 任务的名称
*/
public Task(String name) {
this.initDate = new Date();
this.name = name;
}
/**
* 核心类,执行任务,等待一个随机的时间完成任务
*/
@Override
public void run() {
System.out.printf("%s: Task %s: Created on: %s\n", Thread.currentThread().getName(), name, initDate);
System.out.printf("%s: Task %s: Started on: %s\n", Thread.currentThread().getName(), name, new Date());
try {
Long duration = (long) (Math.random() * 10);
System.out.printf("%s: Task %s: Doing a task during %d seconds\n", Thread.currentThread().getName(), name, duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s: Task %s: Finished on: %s\n", Thread.currentThread().getName(), name, new Date());
}
}
================================================
FILE: 04-03-创建固定大小的线程执行器/04-03-创建固定大小的线程执行器.iml
================================================
================================================
FILE: 04-03-创建固定大小的线程执行器/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Server;
import com.concurrency.task.Task;
public class Main {
public static void main(String[] args) {
Server server = new Server();
// 发送100个任务到服务器对象,并且完成任务
for (int i = 0; i < 100; i++) {
Task task = new Task("Task " + i);
server.executeTask(task);
}
server.endServer();
}
}
================================================
FILE: 04-03-创建固定大小的线程执行器/src/com/concurrency/task/Server.java
================================================
package com.concurrency.task;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 服务类,模拟一个服务器
*/
public class Server {
/**
* 线程池执行器,管理请求线程的执行
*/
private ThreadPoolExecutor executor;
/**
* 构造函数,创建线程执行器对象
*/
public Server() {
executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5); // 本质是一个固定大小的线程池对象
}
/**
* 任务执行方法 接收Task对象作为参数并将其提交到执行者
*
* @param task Task对象
*/
public void executeTask(Task task) {
// 首先,写入一条信息到控制台,表明有一个新的任务到达。
System.out.printf("Server: A new task has arrived\n");
// 然后,调用执行者的execute()方法来提交这个任务
executor.execute(task);
// 最后,将执行者的数据写入到控制台来看它们的状态
System.out.printf("Server: Pool Size: %d\n", executor.getPoolSize());
System.out.printf("Server: Active Count: %d\n", executor.getActiveCount());
System.out.printf("Server: Task Count: %d\n",executor.getTaskCount());
System.out.printf("Server: Completed Tasks: %d\n",executor.getCompletedTaskCount());
}
/**
* 结束执行的方法
*/
public void endServer() {
// 调用执行者的shutdown()方法来结束任务执行
executor.shutdown();
}
}
================================================
FILE: 04-03-创建固定大小的线程执行器/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* 任务类
*/
public class Task implements Runnable {
/**
* 任务创建的时间
*/
private Date initDate;
/**
* 任务的名称
*/
private String name;
/**
* 构造函数,初始化属性
*
* @param name 任务的名称
*/
public Task(String name) {
this.initDate = new Date();
this.name = name;
}
/**
* 核心类,执行任务,等待一个随机的时间完成任务
*/
@Override
public void run() {
System.out.printf("%s: Task %s: Created on: %s\n", Thread.currentThread().getName(), name, initDate);
System.out.printf("%s: Task %s: Started on: %s\n", Thread.currentThread().getName(), name, new Date());
try {
Long duration = (long) (Math.random() * 10);
System.out.printf("%s: Task %s: Doing a task during %d seconds\n", Thread.currentThread().getName(), name, duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s: Task %s: Finished on: %s\n", Thread.currentThread().getName(), name, new Date());
}
}
================================================
FILE: 04-04-在执行器中执行任务并返回结果/04-04-在执行器中执行任务并返回结果.iml
================================================
================================================
FILE: 04-04-在执行器中执行任务并返回结果/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.FactorialCalculator;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class Main {
public static void main(String[] args) {
// 创建固定大小的线程池执行器,最多可以同时执行2个线程。
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
// 创建一个存储未来象的列表,未来对象关联着任务的任务的执行,并且可以获取执行的结果
List> resultList = new ArrayList<>();
// 创建一个随机数生成对象
Random random = new Random();
// 创建10个任务并且将它们送到执行器中
for (int i = 0; i < 10; i++) {
// 生成[0, 10)之间的10个随机数
Integer number = random.nextInt(10);
FactorialCalculator calculator = new FactorialCalculator(number);
// 调用执行器的submit()方法来提交FactorialCalculator任务给执行者。
// 这个方法返回Future对象来管理任务,并且最终获取它的结果。
Future result = executor.submit(calculator);
// 将结果存储到队列当中
resultList.add(result);
}
// 创建一个do循环来监控执行者的状态,等待10个线程都完成任务。
do {
// 首先,写入信息到控制台,使用执行器的getCompletedTaskNumber()方法获得的已完成的任务数。
System.out.printf("Main: Number of Completed Tasks: %d\n", executor.getCompletedTaskCount());
// 然后,对于队列中的10个Future对象,使用isDone()方法,将信息写入(到控制台)表明它们所管理的任务是否已经完成
for (int i = 0; i < resultList.size(); i++) {
Future result = resultList.get(i);
System.out.printf("Main: Task %d: %s\n", i, result.isDone());
}
try {
// 主线程休眠50毫秒
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 如果执行器中的已完成任务数小于10,重复这个循环。
} while (executor.getCompletedTaskCount() < resultList.size());
// 将获得的每个任务的结果写入控制台。对于每个Future对象,通过它的任务使用get()方法获取返回的Integer对象。
System.out.printf("Main: Results\n");
for (int i = 0; i < resultList.size(); i++) {
Future result = resultList.get(i);
Integer number = null;
try {
number = result.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 在控制台输出结果
System.out.printf("Core: Task %d: %d\n", i, number);
}
// 最后,调用执行器的shutdown()方法来结束这个执行器。
executor.shutdown();
}
}
================================================
FILE: 04-04-在执行器中执行任务并返回结果/src/com/concurrency/task/FactorialCalculator.java
================================================
package com.concurrency.task;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
* 阶乘计算类,实现Callable接口,并参数化为Integer类型
*/
public class FactorialCalculator implements Callable {
/**
* 声明一个私有的,类型为Integer,名为number的属性,用来存储任务将要计算的数
*/
private Integer number;
/**
* 构造函数,初始化
* @param number 将要计算的数
*/
public FactorialCalculator(Integer number) {
this.number = number;
}
/**
* 核心方法,返回阶乘计算的结果
* @return 阶乘计算的结果
* @throws Exception
*/
@Override
public Integer call() throws Exception {
int num, result;
num = number;
result = 1;
// 如果数是1或0,则返回1。否则,计算这个数的阶乘。为了演示效果,在两次乘之间,令这个任务睡眠20毫秒。
if (num == 0 || num == 1) {
return 1;
} else {
for (int i = 2; i <= number; i++) {
result *= i;
TimeUnit.MICROSECONDS.sleep(20);
}
}
// 操作结果的信息写入控制台。
System.out.printf("%s: %d\n", Thread.currentThread().getName(), result);
// 返回操作结果。
return result;
}
}
================================================
FILE: 04-05-运行多个任务并处理第一个结果/04-05-运行多个任务并处理第一个结果.iml
================================================
================================================
FILE: 04-05-运行多个任务并处理第一个结果/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.TaskValidator;
import com.concurrency.task.UserValidator;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
// 创建两个String对象,一个名为name,另一个名为password,使用”test”值初始化它们。
String username = "test";
String password = "test";
// 创建两个UserValidator对象,一个名为ldapValidator,另一个名为dbValidator。
UserValidator ldapValidator = new UserValidator("LDAP");
UserValidator dbValidator = new UserValidator("DataBase");
// 创建两个TaskValidator对象,分别为ldapTask和dbTask。分别使用ldapValidator和dbValidator初始化它们。
TaskValidator ldapTask = new TaskValidator(ldapValidator, username, password);
TaskValidator dbTask = new TaskValidator(dbValidator, username, password);
// 创建TaskValidator队列,添加两个已创建的对象(ldapTask和dbTask)
List taskList = new ArrayList<>();
taskList.add(ldapTask);
taskList.add(dbTask);
// 使用Executors类的newCachedThreadPool()方法创建一个新的ThreadPoolExecutor对象和一个类型为String,
// 名为result的变量。
ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool();
String result;
try {
// 调用executor对象的invokeAny()方法。该方法接收taskList参数,返回String类型。
// 同样,它将该方法返回的String对象写入到控制台。
result = executor.invokeAny(taskList);
System.out.printf("Main: Result: %s\n", result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 使用shutdown()方法结束执行者,写入一条信息到控制台,表明程序已结束。
executor.shutdown();
System.out.printf("Main: End of the Execution\n");
}
}
================================================
FILE: 04-05-运行多个任务并处理第一个结果/src/com/concurrency/task/TaskValidator.java
================================================
package com.concurrency.task;
import java.util.concurrent.Callable;
/**
* 任务验证类,用来执行UserValidation对象作为并发任务的验证过程。指定它实现Callable接口,并参数化为String类型。
*/
public class TaskValidator implements Callable {
/**
* 声明一个私有的、类型为UserValidator、名为validator的属性。
*/
private UserValidator validator;
/**
* 声明私有的、类型为String、名为user的属性。
*/
private String user;
/**
* 声明私有的、类型为String、名为password的属性。
*/
private String password;
/**
* 构造函数,初始化属性
*
* @param validator 用户验证对象
* @param user 用户名
* @param password 用户密码
*/
public TaskValidator(UserValidator validator, String user, String password) {
this.validator = validator;
this.user = user;
this.password = password;
}
/**
* 核心方法,使用用户验证对象进行用户名和密码验证,如果验证通过就返回验证的名字,否则就抛出异常
*
* @return 验证的名字
* @throws Exception 验证不通过就抛出异常
*/
@Override
public String call() throws Exception {
// 如果用户没有通过UserValidator对象验证,写入一条信息到控制台,表明这种情况,并且抛出一个Exception异常
if (!validator.validate(user, password)) {
System.out.printf("%s: The user has not been found\n", validator.getName());
throw new Exception("Error validating user");
}
// 否则,写入一条信息到控制台表明用户已通过验证,并返回UserValidator对象的名称。
System.out.printf("%s: The user has been found\n", validator.getName());
return validator.getName();
}
}
================================================
FILE: 04-05-运行多个任务并处理第一个结果/src/com/concurrency/task/UserValidator.java
================================================
package com.concurrency.task;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* 用户检验类,实现用户验证过程
*/
public class UserValidator {
/**
* 声明一个私有的、类型为String、名为name的属性,用来存储系统验证用户的名称。
*/
private String name;
/**
* 构造函数,初始化用户名称
*
* @param name 用户名称
*/
public UserValidator(String name) {
this.name = name;
}
/**
* 验证方法,根据用户名和密码进行验
*
* @param name 用户名
* @param password 密码
* @return true验证通过,false验证失败
*/
public boolean validate(String name, String password) {
// 创建Random对象,名为random。
Random random = new Random();
// 等待一个随机时间,用来模拟用户验证的过程
try {
Long duration = (long) (Math.random() * 10);
System.out.printf("Validator %s: Validating a user during %d seconds\n", this.name, duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
return false;
}
// 返回一个随机Boolean值。如果用户验证通过,这个方法将返回true,否则,返回false。
return random.nextBoolean();
}
/**
* 返回name属性值
*
* @return name属性值
*/
public String getName() {
return name;
}
}
================================================
FILE: 04-06-运行多个任务并且处理所有结果/04-06-运行多个任务并且处理所有结果.iml
================================================
================================================
FILE: 04-06-运行多个任务并且处理所有结果/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Result;
import com.concurrency.task.Task;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
// 使用Executors类的newCachedThreadPool()方法,创建ThreadPoolExecutor对象。
ExecutorService executor = Executors.newCachedThreadPool();
// 创建三个Task对象,并且将他们存储在一个链表当中
List taskList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Task task = new Task("Task-" + i);
taskList.add(task);
}
// 创建Future对象列表,参数化为Result类型。
List> resultList = null;
try {
// 调用ThreadPoolExecutor类的invokeAll()方法。这个类将会返回之前创建的Future对象列表。
resultList = executor.invokeAll(taskList);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 使用shutdown()方法结束执行器的执行。
executor.shutdown();
// 将结果写入控制台
System.out.printf("Core: Printing the results\n");
for (Future future : resultList) {
try {
Result result = future.get();
System.out.printf("%s: %s\n", result.getName(), result.getValue());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
================================================
FILE: 04-06-运行多个任务并且处理所有结果/src/com/concurrency/task/Result.java
================================================
package com.concurrency.task;
/**
* 结果类,存储中并发任务产生的结果
*/
public class Result {
/**
* 产生结果的任务的名字
*/
private String name;
/**
* 产生的结果值
*/
private int value;
/**
* 返回任务的名字
*
* @return 任务的名字
*/
public String getName() {
return name;
}
/**
* 设备任务的名字
*
* @param name 任务的名字
*/
public void setName(String name) {
this.name = name;
}
/**
* 返回结果
*
* @return 结果值
*/
public int getValue() {
return value;
}
/**
* 设置结果
*
* @param value 结果值
*/
public void setValue(int value) {
this.value = value;
}
}
================================================
FILE: 04-06-运行多个任务并且处理所有结果/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
* 任务类,实现Callable接口,参数化为Result类型。
*/
public class Task implements Callable {
/**
* 任务的名称
*/
private String name;
/**
* 构造函数
*
* @param name 初始化任务的名称
*/
public Task(String name) {
this.name = name;
}
/**
* 核心方法,等待一个随机时间,并且计算5个随机数的和
*
* @return 个随机数的和
* @throws Exception
*/
@Override
public Result call() throws Exception {
// 向控制台输出信息
System.out.printf("%s: Staring\n", this.name);
// 等待一个随机的时间
try {
Long duration = (long) (Math.random() * 10);
System.out.printf("%s: Waiting %d seconds for results.\n", this.name, duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 计算随机数的和
int value = 0;
for (int i = 0; i < 5; i++) {
value += (int) (Math.random() * 100);
}
// 创建一个结果对象
Result result = new Result();
result.setName(this.name);
result.setValue(value);
System.out.printf("%s: Ends\n", this.name);
// 返回结果对象
return result;
}
}
================================================
FILE: 04-07-在执行器中延时执行任务/04-07-在执行器中延时执行任务.iml
================================================
================================================
FILE: 04-07-在执行器中延时执行任务/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Task;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建一个定时线程池执行器对象
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
// 使用ScheduledThreadPoolExecutor实例的schedule()方法,初始化和开始一些任务(5个任务)。
System.out.printf("Main: Starting at: %s\n", new Date());
for (int i = 0; i < 5; i++) {
Task task = new Task("Task " + i);
executor.schedule(task, i + 1, TimeUnit.SECONDS);
}
// 关闭线程执行器对象
executor.shutdown();
// 等待线程执行器的完成
try {
// 所有线程必须在24小时内完成,否则就终止未完成的线程
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出完成消息
System.out.printf("Core: Ends at: %s\n", new Date());
}
}
================================================
FILE: 04-07-在执行器中延时执行任务/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.Callable;
/**
* 任务类,实现Callable接口,参数化为String类型。
*/
public class Task implements Callable {
/**
* 任务名称
*/
private String name;
/**
* 构造函数,初始化任务名称
*
* @param name 任务名称
*/
public Task(String name) {
this.name = name;
}
/**
* 核心方法,输出任务执行时间
*
* @return 执行结果字符串
* @throws Exception
*/
@Override
public String call() throws Exception {
System.out.printf("%s: Starting at : %s\n", name, new Date());
return "Hello, world";
}
}
================================================
FILE: 04-08-在执行器中周期性执行任务/04-08-在执行器中周期性执行任务.iml
================================================
================================================
FILE: 04-08-在执行器中周期性执行任务/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Task;
import java.util.Date;
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
// 创建一个定时行器服务对象
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
System.out.printf("Main: Starting at: %s\n", new Date());
// 创建一个执行任务,并且将它放入执行器中,初始延迟是1秒,周期是2秒
Task task = new Task("Task");
ScheduledFuture> result = executor.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS);
// 控制任务的执行
for (int i = 0; i < 10; i++) {
System.out.printf("Main: Delay: %d\n", result.getDelay(TimeUnit.MILLISECONDS));
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 关闭执行器对象
executor.shutdown();
System.out.printf("Main: No more tasks at: %s\n", new Date());
// 验证在执行器关闭后,周期性任务不会执行
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出完成信息
System.out.printf("Main: Finished at: %s\n", new Date());
}
}
================================================
FILE: 04-08-在执行器中周期性执行任务/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.Date;
/**
* 任务类,执行任务
*/
public class Task implements Runnable {
/**
* 任务的名称
*/
private String name;
/**
* 构造函数,初始化任务名称
*
* @param name 任务名称
*/
public Task(String name) {
this.name = name;
}
/**
* 核心方法,向控制台输出当前执行的时间
*/
@Override
public void run() {
System.out.printf("%s: Executed at: %s\n",name,new Date());
}
}
================================================
FILE: 04-09-在执行器中取消任务/04-09-在执行器中取消任务.iml
================================================
================================================
FILE: 04-09-在执行器中取消任务/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Task;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建一个执行器
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
// 创建一个任务
Task task = new Task();
System.out.printf("Main: Executing the Task\n");
// 把任务发送到执行器
Future result = executor.submit(task);
// 休眠两秒钟
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 取消一个任务完成他的执行
System.out.printf("Main: Cancelling the Task\n");
result.cancel(true);
// 验证任务是否被取消
System.out.printf("Main: Cancelled: %s\n", result.isCancelled());
System.out.printf("Main: Done: %s\n", result.isDone());
// 关闭执行器
executor.shutdown();
System.out.printf("Main: The executor has finished\n");
}
}
================================================
FILE: 04-09-在执行器中取消任务/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.concurrent.Callable;
public class Task implements Callable {
/**
* 核心方法,一个无限循环的任务,每100毫秒向控制台写一个消息
* @return
* @throws Exception
*/
@Override
public String call() throws Exception {
while (true){
System.out.printf("Task: Test\n");
Thread.sleep(100);
}
}
}
================================================
FILE: 04-10-在执行器中控制任务的完成/04-10-在执行器中控制任务的完成.iml
================================================
================================================
FILE: 04-10-在执行器中控制任务的完成/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.ExecutableTask;
import com.concurrency.task.ResultTask;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建一个执行器对象
ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool();
// 创建5个任务
ResultTask resultTasks[] = new ResultTask[5];
for (int i = 0; i < 5; i++) {
ExecutableTask executableTask = new ExecutableTask("Task " + i);
resultTasks[i] = new ResultTask(executableTask);
executor.submit(resultTasks[i]);
}
// 休眠5秒钟
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
// 取消所有的任务,如果任务在取消之前已经完,取消操作对任务没有任命影响
for (ResultTask resultTask : resultTasks) {
resultTask.cancel(true);
}
// 输出未被取消的任务的结果
for (ResultTask resultTask : resultTasks) {
try {
if (!resultTask.isCancelled()) {
System.out.printf("%s\n", resultTask.get());
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
// 关闭执行器
executor.shutdown();
}
}
================================================
FILE: 04-10-在执行器中控制任务的完成/src/com/concurrency/task/ExecutableTask.java
================================================
package com.concurrency.task;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
* 任务执行类,并指定其实现Callable接口,参数化为String类型。
*/
public class ExecutableTask implements Callable {
/**
* 任务名称
*/
private String name;
public ExecutableTask(String name) {
this.name = name;
}
/**
* 核心方法,等待一个随机时间,返回一个结果
*
* @return 字符串结果
* @throws Exception
*/
@Override
public String call() throws Exception {
try {
Long duration = (long) (Math.random() * 10);
System.out.printf("%s: Waiting %d seconds for results.\n", this.name, duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
//e.printStackTrace();
}
return "Hello, world. I'm " + name;
}
/**
* 获取任务名称
*
* @return 任务名称
*/
public String getName() {
return name;
}
}
================================================
FILE: 04-10-在执行器中控制任务的完成/src/com/concurrency/task/ResultTask.java
================================================
package com.concurrency.task;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* 结果任务类,这个类管理着可执行任务类的执行
*/
public class ResultTask extends FutureTask {
/**
* 结果任务的名称
*/
private String name;
/**
* 构造函数
*
* @param callable 可调用的接口对象
*/
public ResultTask(Callable callable) {
super(callable);
this.name = ((ExecutableTask) callable).getName();
}
/**
* 当任务完成时调用这个方法
*/
@Override
protected void done() {
if (isCancelled()) {
System.out.printf("%s: Has been cancelled\n", name);
} else {
System.out.printf("%s: Has finished\n", name);
}
}
}
================================================
FILE: 04-11-在执行器中分离任务的启动与结果的处理/04-11-在执行器中分离任务的启动与结果的处理.iml
================================================
================================================
FILE: 04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.ReportProcessor;
import com.concurrency.task.ReportRequest;
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
// 创建一个执行器对象和三个完成服务对象,执行器对象供完成服务对象使用
ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool();
CompletionService service = new ExecutorCompletionService<>(executor);
// 创建两报表请求对象和两个线程来执行他们
ReportRequest faceRequest = new ReportRequest("Face", service);
ReportRequest onlineRequest = new ReportRequest("Online", service);
Thread faceThread = new Thread(faceRequest);
Thread onlineThread = new Thread(onlineRequest);
// 创建一个报表处理对象和一个执行它的线程
ReportProcessor processor = new ReportProcessor(service);
Thread senderThread = new Thread(processor);
// 启动线程
System.out.printf("Main: Starting the Threads\n");
faceThread.start();
onlineThread.start();
senderThread.start();
// 等待报表生成器对象的任务完成
try {
System.out.printf("Main: Waiting for the report generators.\n");
faceThread.join();
onlineThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 关闭执行器
System.out.printf("Main: Shuting down the executor.\n");
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 等待报表发送器对象执行结束
processor.setEnd(true);
System.out.printf("Main: Ends\n");
}
}
================================================
FILE: 04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/task/ReportGenerator.java
================================================
package com.concurrency.task;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
* 报告生成类,模拟生成报告。
*/
public class ReportGenerator implements Callable {
/**
* 报告发送者
*/
private String sender;
/**
* 报告的标题
*/
private String title;
/**
* 构造函数,初始化报告发送者,报告的标题
*
* @param sender 报告发送者
* @param title 报告的标题
*/
public ReportGenerator(String sender, String title) {
this.sender = sender;
this.title = title;
}
/**
* 核心方法,等待一个随机时间,产生一个字符串类型的报告
*
* @return 字符串类型的报告
* @throws Exception
*/
@Override
public String call() throws Exception {
try {
Long duration = (long) (Math.random() * 10);
System.out.printf("%s_%s: ReportGenerator: Generating a report during %d seconds\n", this.sender, this.title, duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
String ret = sender + ": " + title;
return ret;
}
}
================================================
FILE: 04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/task/ReportProcessor.java
================================================
package com.concurrency.task;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* 报表处理器类,通过CompletionService对象处理报表生成器的结果
*/
public class ReportProcessor implements Runnable {
/**
* 完成服务对象
*/
private CompletionService service;
/**
* 任务完成的标记
*/
private boolean end;
/**
* 构造函数,初始化完成服务对象
*
* @param service 完成服务对象
*/
public ReportProcessor(CompletionService service) {
this.service = service;
}
/**
* 核心方法,如果任务没有完成就一直执行
*/
@Override
public void run() {
while (!end) {
try {
// 调用CompletionService接口的poll()方法,获取CompletionService执行的下个已完成任务的Future对象
Future result = service.poll(20, TimeUnit.SECONDS);
if (result != null) {
// 使用Future对象的get()方法获取任务的结果,并且将这些结果写入到控制台
String report = result.get();
System.out.printf("ReportReceiver: Report Received: %s\n", report);
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
System.out.printf("ReportSender: End\n");
}
/**
* 设置任务完成标记
* @param end 任务完成标记
*/
public void setEnd(boolean end) {
this.end = end;
}
}
================================================
FILE: 04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/task/ReportRequest.java
================================================
package com.concurrency.task;
import java.util.concurrent.CompletionService;
/**
* 报告请求类
*/
public class ReportRequest implements Runnable {
/**
* 报告请求类的名字
*/
private String name;
/**
* 完成任务对象
*/
private CompletionService service;
/**
* 构造函数,初始化报告请求类的名字,完成任务对象
*
* @param name 报告请求类的名字
* @param service 完成任务对象
*/
public ReportRequest(String name, CompletionService service) {
this.name = name;
this.service = service;
}
/**
* 核心方法,创建一个报告生成对象,并且将其提交到完成任务对象
*/
@Override
public void run() {
ReportGenerator reportGenerator = new ReportGenerator(name, "Report");
service.submit(reportGenerator);
}
}
================================================
FILE: 04-12-处理在执行器中被拒绝的任务/04-12-处理在执行器中被拒绝的任务.iml
================================================
================================================
FILE: 04-12-处理在执行器中被拒绝的任务/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.RejectedTaskController;
import com.concurrency.task.Task;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class Main {
public static void main(String[] args) {
// 创建拒绝任务控制器对象
// Create the controller for the Rejected tasks
RejectedTaskController controller = new RejectedTaskController();
// 创建执行器对象,并且设置拒绝执行处理器对象
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
executor.setRejectedExecutionHandler(controller);
// 运行三个任务
System.out.printf("Main: Starting.\n");
for (int i = 0; i < 3; i++) {
Task task = new Task("Task" + i);
executor.submit(task);
}
// 关闭执行器
System.out.printf("Main: Shuting down the Executor.\n");
executor.shutdown();
// 发送另外一个任务
System.out.printf("Main: Sending another Task.\n");
Task task = new Task("RejectedTask");
executor.submit(task);
// 程序结束
System.out.printf("Main: End.\n");
}
}
================================================
FILE: 04-12-处理在执行器中被拒绝的任务/src/com/concurrency/task/RejectedTaskController.java
================================================
package com.concurrency.task;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 拒绝任务处理器类
*/
public class RejectedTaskController implements RejectedExecutionHandler {
/**
* 核心方法,在控制台输出已被拒绝的任务的名称和 执行器的状态。
* @param r
* @param executor
*/
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.printf("RejectedTaskController: The task %s has been rejected\n", r.toString());
System.out.printf("RejectedTaskController: %s\n", executor.toString());
System.out.printf("RejectedTaskController: Terminating: %s\n", executor.isTerminating());
System.out.printf("RejectedTasksController: Terminated: %s\n", executor.isTerminated());
}
}
================================================
FILE: 04-12-处理在执行器中被拒绝的任务/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
/**
* 任务类,执行一个随机时间的任务
*/
public class Task implements Runnable {
private String name;
public Task(String name) {
this.name = name;
}
@Override
public void run() {
System.out.printf("Task %s: Starting\n", name);
try {
Long duration = (long) (Math.random() * 10);
System.out.printf("Task %s: ReportGenerator: Generating a report during %d seconds\n", name, duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Task %s: Ending\n", name);
}
@Override
public String toString() {
return name;
}
}
================================================
FILE: 05-02-创建Fork-Join线程池/05-02-创建Fork-Join线程池.iml
================================================
================================================
FILE: 05-02-创建Fork-Join线程池/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Task;
import com.concurrency.utils.Product;
import com.concurrency.utils.ProductListGenerator;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建产品生成器对象,并且门生产10000个产品
ProductListGenerator generator = new ProductListGenerator();
List products = generator.generate(10000);
// 创建一个任务对象
Task task = new Task(products, 0, products.size(), 0.2);
// 创建一个分合池
ForkJoinPool pool = new ForkJoinPool();
// 执行任务
pool.execute(task);
// 输出分合池的信息
do {
System.out.printf("Main: Thread Count: %d\n", pool.getActiveThreadCount());
System.out.printf("Main: Thread Steal: %d\n", pool.getStealCount());
System.out.printf("Main: Paralelism: %d\n", pool.getParallelism());
try {
TimeUnit.MILLISECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (!task.isDone());
// 关闭分合池
pool.shutdown();
// 检查任务是否正常完成
if (task.isCompletedNormally()) {
System.out.printf("Main: The process has completed normally.\n");
}
// 输出价格不是12的产品
for (Product product : products) {
if (product.getPrice() != 12) {
System.out.printf("Product %s: %f\n", product.getName(), product.getPrice());
}
}
// 结束程序
System.out.println("Main: End of the program.\n");
}
}
================================================
FILE: 05-02-创建Fork-Join线程池/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import com.concurrency.utils.Product;
import java.util.List;
import java.util.concurrent.RecursiveAction;
/**
*任务执行类,如果产品多于10个就让分出子任务进行处理
*/
public class Task extends RecursiveAction {
private static final long serialVersionUID = 6876633274768462482L;
/**
* 产品集合对象
*/
private List products;
/**
* 处理的第一个产品位置
*/
private int first;
/**
* 处理的最后一个产品位置
*/
private int last;
/**
* 价格增长率
*/
private double increment;
/**
* 构造函数,初始化属性
*
* @param products 产品集合对象
* @param first 处理的第一个产品位置
* @param last 处理的最后一个产品位置(不包含)
* @param increment 价格增长率
*/
public Task(List products, int first, int last, double increment) {
this.products = products;
this.first = first;
this.last = last;
this.increment = increment;
}
/**
* 对产品进行计算
*/
@Override
protected void compute() {
if (last - first < 10) { // 处理的产品数少于10个就提价
updatePrices();
} else { // 否则就让两个子线程去执行
int middle = (first + last) / 2;
System.out.printf("Task: Pending tasks: %s\n", getQueuedTaskCount());
Task t1 = new Task(products, first, middle + 1, increment);
Task t2 = new Task(products, middle + 1, last, increment);
invokeAll(t1, t2);
}
}
/**
* 更价格,将指定的范围内的产品提价
*/
private void updatePrices() {
for (int i = first; i < last; i++) {
Product product = products.get(i);
product.setPrice(product.getPrice() * (1 + increment)); // 按increment比率提价
}
}
}
================================================
FILE: 05-02-创建Fork-Join线程池/src/com/concurrency/utils/Product.java
================================================
package com.concurrency.utils;
/**
* 产品类,保存产品的名称和价格
*/
public class Product {
/**
* 名称
*/
private String name;
/**
* 价格
*/
private double price;
/**
* 获取产品名称
*
* @return 产品名称
*/
public String getName() {
return name;
}
/**
* 设置产名品名称
*
* @param name 产名名称
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取产品价格
*
* @return 产品价格
*/
public double getPrice() {
return price;
}
/**
* 设置产品价格
*
* @param price 产品价格
*/
public void setPrice(double price) {
this.price = price;
}
}
================================================
FILE: 05-02-创建Fork-Join线程池/src/com/concurrency/utils/ProductListGenerator.java
================================================
package com.concurrency.utils;
import java.util.ArrayList;
import java.util.List;
/**
* 产品生成器类,根据指定的数量创建产品
*/
public class ProductListGenerator {
/**
* 产品生产类
*
* @param size 产品数量
* @return 产品集合
*/
public List generate(int size) {
List ret = new ArrayList<>();
for (int i = 0; i < size; i++) {
Product product = new Product();
product.setName("Product " + i);
product.setPrice(10);
ret.add(product);
}
return ret;
}
}
================================================
FILE: 05-03-合并任务的结果/05-03-合并任务的结果.iml
================================================
================================================
FILE: 05-03-合并任务的结果/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.DocumentTask;
import com.concurrency.utils.DocumentMock;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建一个模拟文档,他有100行,每行1000个单词
// Generate a document with 100 lines and 1000 words per line
DocumentMock mock = new DocumentMock();
String[][] document = mock.generateDocument(100, 1000, "the");
// 创建一个文档任务对象,处理整个文档
DocumentTask task = new DocumentTask(document, 0, 100, "the");
// 创建一个分合池对象
ForkJoinPool pool = new ForkJoinPool();
// 执行文档处理任务
pool.execute(task);
// 输出分合池对象的统计数据
do {
System.out.printf("******************************************\n");
System.out.printf("Main: Parallelism: %d\n", pool.getParallelism());
System.out.printf("Main: Active Threads: %d\n", pool.getActiveThreadCount());
System.out.printf("Main: Task Count: %d\n", pool.getQueuedTaskCount());
System.out.printf("Main: Steal Count: %d\n", pool.getStealCount());
System.out.printf("******************************************\n");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (!task.isDone());
// 关闭分合池
pool.shutdown();
// 等待所有的任务完成
try {
pool.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出任务完成的结果
try {
System.out.printf("Main: The word appears %d in the document", task.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 05-03-合并任务的结果/src/com/concurrency/task/DocumentTask.java
================================================
package com.concurrency.task;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;
/**
* 文档处理类,在文档中查找指定的单词
*/
public class DocumentTask extends RecursiveTask {
private static final long serialVersionUID = -1257254196502539272L;
/**
* 等待处理的文档
*/
private String document[][];
/**
* 文档处理的开始行
*/
private int start;
/**
* 文档处理的结束行
*/
private int end;
/**
* 要查找的单词
*/
private String word;
/**
* 构造函数
*
* @param document 等待处理的文档
* @param start 文档处理的开始行
* @param end 文档处理的结束行
* @param word 要查找的单词
*/
public DocumentTask(String document[][], int start, int end, String word) {
this.document = document;
this.start = start;
this.end = end;
this.word = word;
}
/**
* 核心方法,统计文档的中指定的单词
*
* @return 指定的单词出现的次数
*/
@Override
protected Integer compute() {
Integer result = null;
if (end - start < 10) { // 少于10行,使用行处理方法
result = processLines(document, start, end, word);
} else { // 否则使用两个线程去处理
int mid = (start + end) / 2;
DocumentTask task1 = new DocumentTask(document, start, mid, word);
DocumentTask task2 = new DocumentTask(document, mid, end, word);
invokeAll(task1, task2);
try {
result = groupResults(task1.get(), task2.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 返回number1+number2的和
*
* @param number1 加数l
* @param number2 加数2
* @return 和
*/
private Integer groupResults(Integer number1, Integer number2) {
return number1 + number2;
}
/**
* 行处理方法
*
* @param document 等待处理的文档
* @param start 文档处理的开始行
* @param end 文档处理的结束行
* @param word 要查找的单词
* @return 指定的单词出现的次数
*/
private Integer processLines(String[][] document, int start, int end, String word) {
List tasks = new ArrayList();
// 有多少行就创建多少个行处理任务对象
for (int i = start; i < end; i++) {
LineTask task = new LineTask(document[i], 0, document[i].length, word);
tasks.add(task);
}
invokeAll(tasks);
// 统计结果
int result = 0;
for (LineTask task : tasks) {
try {
result = result + task.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return result;
}
}
================================================
FILE: 05-03-合并任务的结果/src/com/concurrency/task/LineTask.java
================================================
package com.concurrency.task;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
/**
* 行处理类,处理指定行数和单词
*/
public class LineTask extends RecursiveTask {
private static final long serialVersionUID = 4169105159737293155L;
/**
* 文档中一行数据
*/
private String line[];
/**
* 行处理的起始位置
*/
private int start;
/**
* 行处理的结束位置
*/
private int end;
/**
* 要查找的单词
*/
private String word;
/**
* 构造函数
*
* @param line 文档中一行数据
* @param start 行处理的起始位置
* @param end 行处理的结束位置
* @param word 要查找的单词
*/
public LineTask(String line[], int start, int end, String word) {
this.line = line;
this.start = start;
this.end = end;
this.word = word;
}
/**
* 核心方法,完成单词的查找
*
* @return 查找范围内,单词出现的次数
*/
@Override
protected Integer compute() {
Integer result = null;
if (end - start < 100) { // 少于100个单词就进行统计
result = count(line, start, end, word);
} else { // 否则就分成两个线程进行处理
int mid = (start + end) / 2;
LineTask task1 = new LineTask(line, start, mid + 1, word);
LineTask task2 = new LineTask(line, mid + 1, end, word);
invokeAll(task1, task2);
try {
result = groupResults(task1.get(), task2.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 返回number1+number2的和
*
* @param number1 加数l
* @param number2 加数2
* @return 和
*/
private Integer groupResults(Integer number1, Integer number2) {
return number1 + number2;
}
/**
* 统计单词出现的次数
*
* @param line 待待查找的行
* @param start 处理的开始位置
* @param end 处理的结束位置
* @param word 查找的单词
* @return 单词出现的次数
*/
private Integer count(String[] line, int start, int end, String word) {
int counter;
counter = 0;
for (int i = start; i < end; i++) {
if (line[i].equals(word)) {
counter++;
}
}
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return counter;
}
}
================================================
FILE: 05-03-合并任务的结果/src/com/concurrency/utils/DocumentMock.java
================================================
package com.concurrency.utils;
import java.util.Random;
/**
* 文档模拟对象,根据指定的列数和每行单词数生成文档
*/
public class DocumentMock {
/**
* 文档中的单词集合
*/
private String words[] = {"the", "hello", "goodbye", "packt", "java", "thread", "pool", "random", "class", "main"};
/**
* 生成文档
*
* @param numLines 文档行数
* @param numWords 每行单词数
* @param word 文档中要查找的单词
* @return 文档
*/
public String[][] generateDocument(int numLines, int numWords, String word) {
int counter = 0;
String document[][] = new String[numLines][numWords];
Random random = new Random();
for (int i = 0; i < numLines; i++) {
for (int j = 0; j < numWords; j++) {
int index = random.nextInt(words.length);
document[i][j] = words[index];
if (document[i][j].equals(word)) {
counter++;
}
}
}
System.out.printf("DocumentMock: The word appears %d times in the document.\n", counter);
return document;
}
}
================================================
FILE: 05-04-异步运行任务/05-04-异步运行任务.iml
================================================
================================================
FILE: 05-04-异步运行任务/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.FolderProcessor;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建分合池
ForkJoinPool pool = new ForkJoinPool();
// 为三个不同的文件夹创建文件处理器对象
FolderProcessor system = new FolderProcessor("C:\\Windows", "log");
FolderProcessor apps = new FolderProcessor("C:\\Program Files", "log");
FolderProcessor documents = new FolderProcessor("C:\\Documents And Settings", "log");
// 在分合池中执行一个任务
pool.execute(system);
pool.execute(apps);
pool.execute(documents);
// 输出统计信息,直到三个任务都完成
do {
System.out.printf("******************************************\n");
System.out.printf("Main: Parallelism: %d\n", pool.getParallelism());
System.out.printf("Main: Active Threads: %d\n", pool.getActiveThreadCount());
System.out.printf("Main: Task Count: %d\n", pool.getQueuedTaskCount());
System.out.printf("Main: Steal Count: %d\n", pool.getStealCount());
System.out.printf("******************************************\n");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while ((!system.isDone()) || (!apps.isDone()) || (!documents.isDone()));
// 关闭分合池
pool.shutdown();
// 保存每个任务统计的结束
List results;
results = system.join();
System.out.printf("System: %d files found.\n", results.size());
results = apps.join();
System.out.printf("Apps: %d files found.\n", results.size());
results = documents.join();
System.out.printf("Documents: %d files found.\n", results.size());
}
}
================================================
FILE: 05-04-异步运行任务/src/com/concurrency/task/FolderProcessor.java
================================================
package com.concurrency.task;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveTask;
/**
* 文件夹处理类,查找指定文件夹及其子文件夹下的指定后缀名的文件
*/
public class FolderProcessor extends RecursiveTask> {
private static final long serialVersionUID = -6119741136325003142L;
/**
* 开始处理的文件目录
*/
private String path;
/**
* 要查找的文件后缀名
*/
private String extension;
/**
* 构造函数
*
* @param path 开始处理的文件目录
* @param extension 要查找的文件后缀名
*/
public FolderProcessor(String path, String extension) {
this.path = path;
this.extension = extension;
}
/**
* 核心方法,查找文件夹下所有指定后缀的文件,如果是一个文件夹就开创建子线程去运行
*
* @return 查找到的文件集合
*/
@Override
protected List compute() {
List list = new ArrayList<>();
List tasks = new ArrayList<>();
File file = new File(path);
File content[] = file.listFiles();
if (content != null) {
for (int i = 0; i < content.length; i++) {
if (content[i].isDirectory()) {
FolderProcessor task = new FolderProcessor(content[i].getAbsolutePath(), extension);
task.fork();
tasks.add(task);
} else {
if (checkFile(content[i].getName())) {
list.add(content[i].getAbsolutePath());
}
}
}
if (tasks.size() > 50) {
System.out.printf("%s: %d tasks ran.\n", file.getAbsolutePath(), tasks.size());
}
addResultsFromTasks(list, tasks);
}
return list;
}
/**
* 汇总统计结果
*
* @param list 结果存放的集合
* @param tasks 任务集合
*/
private void addResultsFromTasks(List list, List tasks) {
for (FolderProcessor item : tasks) {
list.addAll(item.join());
}
}
/**
* 检查文件是否以指定的名称结束
*
* @param name 文件扩展名
* @return true以指定的名字结束,false不以指定的名字结束
*/
private boolean checkFile(String name) {
return name.endsWith(extension);
}
}
================================================
FILE: 05-05-在任务中抛出异常/05-05-在任务中抛出异常.iml
================================================
================================================
FILE: 05-05-在任务中抛出异常/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Task;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建长度为100的整形数组
int array[] = new int[100];
// 创建处理数组的任务
Task task = new Task(array, 0, 100);
// 创建分合池对象去执行这个任务
ForkJoinPool pool = new ForkJoinPool();
// 执行任务
pool.execute(task);
// 关闭分合池
pool.shutdown();
// 等待任务的完成
try {
pool.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 检查是否抛出异常,如果抛出异常就输出信息
if (task.isCompletedAbnormally()) {
System.out.printf("Main: An exception has ocurred\n");
System.out.printf("Main: %s\n", task.getException());
}
System.out.printf("Main: Result: %d", task.join());
}
}
================================================
FILE: 05-05-在任务中抛出异常/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
/**
* 任务执行方法
*/
public class Task extends RecursiveTask {
/**
* 序列化版本号
*/
private static final long serialVersionUID = 1L;
/**
* 待处理的数组
*/
private int array[];
/**
* 任务处理的起始位置
*/
private int start;
/**
* 任务处理的结束位置
*/
private int end;
/**
* 构造函数
*
* @param array 待处理的数组
* @param start 任务处理的起始位置
* @param end 任务处理的结束位置
*/
public Task(int array[], int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
/**
* 核心方法,如果处理的元素大于9个就分成两个任务去执行它,如果处理的起始位置小于3,结束位置大于3就抛出异常
*/
@Override
protected Integer compute() {
System.out.printf("Task: Start from %d to %d\n", start, end);
if (end - start < 10) {
if ((3 > start) && (3 < end)) {
throw new RuntimeException("This task throws an Exception: Task from " + start + " to " + end);
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
int mid = (end + start) / 2;
Task task1 = new Task(array, start, mid);
Task task2 = new Task(array, mid, end);
invokeAll(task1, task2);
System.out.printf("Task: Result form %d to %d: %d\n", start, mid, task1.join());
System.out.printf("Task: Result form %d to %d: %d\n", mid, end, task2.join());
}
System.out.printf("Task: End form %d to %d\n", start, end);
return 0;
}
}
================================================
FILE: 05-06-取消任务/05-06-取消任务.iml
================================================
================================================
FILE: 05-06-取消任务/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.TaskManager;
import com.concurrency.utils.ArrayGenerator;
import com.concurrency.utils.SearchNumberTask;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建一个数组生成器对象,生成一个长度为1000的整形数组
ArrayGenerator generator = new ArrayGenerator();
int array[] = generator.generateArray(1000);
// 创建一个任务管理对象
TaskManager manager = new TaskManager();
// 使用默认的构造函数,创建一个分合池对象
ForkJoinPool pool = new ForkJoinPool();
// 创建一个处理任务的数组
SearchNumberTask task = new SearchNumberTask(array, 0, 1000, 5, manager);
//执行任务
pool.execute(task);
// 关闭这个池
pool.shutdown();
// 等待任务完成
try {
pool.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出信息,表示程序已经完成
System.out.printf("Main: The program has finished\n");
}
}
================================================
FILE: 05-06-取消任务/src/com/concurrency/task/TaskManager.java
================================================
package com.concurrency.task;
import com.concurrency.utils.SearchNumberTask;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinTask;
/**
* 任务管理类
*/
public class TaskManager {
/**
* 任务列表对象
*/
private List> tasks;
/**
* 构造函数,初始化任务值列表对象
*/
public TaskManager(){
tasks=new ArrayList<>();
}
/**
* 在列表中添加一个新的任务
* @param task 新的任务
*/
public void addTask(ForkJoinTask task){
tasks.add(task);
}
/**
* 取消队列中的指定任务
* @param cancelTask 指定的任务
*/
public void cancelTasks(ForkJoinTask cancelTask){
for (ForkJoinTask task :tasks) {
if (task!=cancelTask) {
task.cancel(true);
((SearchNumberTask)task).writeCancelMessage();
}
}
}
}
================================================
FILE: 05-06-取消任务/src/com/concurrency/utils/ArrayGenerator.java
================================================
package com.concurrency.utils;
import java.util.Random;
/**
* 整形数组生成类
*/
public class ArrayGenerator {
/**
* 生成整形数组,生成的值在[0, size)
* @param size 数组长度
* @return 长度为size的数组
*/
public int[] generateArray(int size) {
int array[] = new int[size];
Random random = new Random();
for (int i = 0; i < size; i++) {
array[i] = random.nextInt(10);
}
return array;
}
}
================================================
FILE: 05-06-取消任务/src/com/concurrency/utils/SearchNumberTask.java
================================================
package com.concurrency.utils;
import com.concurrency.task.TaskManager;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
/**
* 数值查找类,在数组中查找指定的数值
*/
public class SearchNumberTask extends RecursiveTask {
/**
* 序列化版本号
*/
private static final long serialVersionUID = 1L;
/**
* 如果没有找到指定的值就返回-1
*/
private final static int NOT_FOUND = -1;
/**
* 待查找的数据
*/
private int numbers[];
/**
* 数组处理的开始位置
*/
private int start;
/**
* 数据处理的结束位置
*/
private int end;
/**
* 要查找的数值
*/
private int number;
/**
* 任务管理器对象,可以对任务进行取消操作
*/
private TaskManager manager;
/**
* 构造函数,初始化属性
*
* @param numbers 待查找的数据
* @param start 数组处理的开始位置
* @param end 数据处理的结束位置
* @param number 要查找的数值
* @param manager 任务管理器对象
*/
public SearchNumberTask(int numbers[], int start, int end, int number, TaskManager manager) {
this.numbers = numbers;
this.start = start;
this.end = end;
this.number = number;
this.manager = manager;
}
/**
* 核心方法,如查处理的数组数目大于10就调用launchTasks()方法,否则lookForNumber()
*
* @return 查找到的位置
*/
@Override
protected Integer compute() {
System.out.println("Task: " + start + ":" + end);
int ret;
if (end - start > 10) {
ret = launchTasks();
} else {
ret = lookForNumber();
}
return ret;
}
/**
* 数据查找方法,找出[start, end)中第一次number出现的位置
*
* @return [start, end)中第一次number出现的位置
*/
private int lookForNumber() {
for (int i = start; i < end; i++) {
if (numbers[i] == number) {
System.out.printf("Task: Number %d found in position %d\n", number, i);
manager.cancelTasks(this); // 取消任务的执行
return i;
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return NOT_FOUND;
}
/**
* 运行任务的方法,分成 两个任务运行
*
* @return [start, end)中第一次number出现的位置
*/
private int launchTasks() {
int mid = (start + end) / 2;
SearchNumberTask task1 = new SearchNumberTask(numbers, start, mid, number, manager);
SearchNumberTask task2 = new SearchNumberTask(numbers, mid, end, number, manager);
manager.addTask(task1);
manager.addTask(task2);
task1.fork();
task2.fork();
int returnValue;
returnValue = task1.join();
if (returnValue != -1) {
return returnValue;
}
returnValue = task2.join();
return returnValue;
}
public void writeCancelMessage() {
System.out.printf("Task: Cancelled task from %d to %d\n", start, end);
}
}
================================================
FILE: 06-02-使用非阻塞式线程安全列表/06-02-使用非阻塞式线程安全列表.iml
================================================
================================================
FILE: 06-02-使用非阻塞式线程安全列表/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.AddTask;
import com.concurrency.task.PollTask;
import java.util.concurrent.ConcurrentLinkedDeque;
public class Main {
public static void main(String[] args) throws Exception {
// 创建一个并发双向队列对象
ConcurrentLinkedDeque list = new ConcurrentLinkedDeque<>();
// 创建长度为100的线程数组
Thread threads[] = new Thread[100];
// 创建100个AddTask对象,并且让他们在各自的线程中运行
for (int i = 0; i < threads.length; i++) {
AddTask task = new AddTask(list);
threads[i] = new Thread(task);
threads[i].start();
}
System.out.printf("Main: %d AddTask threads have been launched\n", threads.length);
// 等待所有的线程执行完
for (Thread thread : threads) {
thread.join();
}
// 输出队列长度信息
System.out.printf("Main: Size of the List: %d\n", list.size());
// 创建100个PollTask对象,并且让他们在各自的线程中运行
for (int i = 0; i < threads.length; i++) {
PollTask task = new PollTask(list);
threads[i] = new Thread(task);
threads[i].start();
}
System.out.printf("Main: %d PollTask threads have been launched\n", threads.length);
// 等待线程执行完
for (Thread thread : threads) {
thread.join();
}
// 输出队列长度信息
System.out.printf("Main: Size of the List: %d\n", list.size());
}
}
================================================
FILE: 06-02-使用非阻塞式线程安全列表/src/com/concurrency/task/AddTask.java
================================================
package com.concurrency.task;
import java.util.concurrent.ConcurrentLinkedDeque;
/**
* 添加数据任务类,向并发队列中添加10000个数据
*/
public class AddTask implements Runnable {
/**
* 等待添加数组的队列
*/
private ConcurrentLinkedDeque list;
/**
* 构造函数
*
* @param list 等待添加数组的队列
*/
public AddTask(ConcurrentLinkedDeque list) {
this.list = list;
}
/**
* 核心方法,向并发队列中添加10000个数据
*/
@Override
public void run() {
String name = Thread.currentThread().getName();
for (int i = 0; i < 10000; i++) {
list.add(name + ": Element " + i);
}
}
}
================================================
FILE: 06-02-使用非阻塞式线程安全列表/src/com/concurrency/task/PollTask.java
================================================
package com.concurrency.task;
import java.util.concurrent.ConcurrentLinkedDeque;
/**
* 取数据任务类,从并发队列中删除10000个数据
*/
public class PollTask implements Runnable {
/**
* 待删除元素的队列
*/
private ConcurrentLinkedDeque list;
/**
* 构造函数
*
* @param list 待删除元素的队列
*/
public PollTask(ConcurrentLinkedDeque list) {
this.list = list;
}
/**
* 核心方法,在并发队列的头部和尾部各删除5000个元素
*/
@Override
public void run() {
for (int i = 0; i < 5000; i++) {
list.pollFirst();
list.pollLast();
}
}
}
================================================
FILE: 06-03-使用阻塞式线程安全列表/06-03-使用阻塞式线程安全列表.iml
================================================
================================================
FILE: 06-03-使用阻塞式线程安全列表/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Client;
import java.util.Date;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
// 创建一个并发链式双向队列
LinkedBlockingDeque list = new LinkedBlockingDeque<>(3);
Client client = new Client(list);
Thread thread = new Thread(client);
thread.start();
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 3; j++) {
String request = list.take();
System.out.printf("Main: Request: %s at %s. Size: %d\n", request, new Date(), list.size());
}
TimeUnit.MILLISECONDS.sleep(300);
}
System.out.printf("Main: End of the program.\n");
}
}
================================================
FILE: 06-03-使用阻塞式线程安全列表/src/com/concurrency/task/Client.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
/**
* ݵ
*/
public class Client implements Runnable {
private LinkedBlockingDeque requestList;
public Client(LinkedBlockingDeque requestList) {
this.requestList = requestList;
}
/**
* ķ15
*/
@Override
public void run() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
StringBuilder request = new StringBuilder();
request.append(i);
request.append(":");
request.append(j);
try {
requestList.put(request.toString());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Client: %s at %s.\n", request, new Date());
}
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("Client: End.\n");
}
}
================================================
FILE: 06-04-使用按优先级排序的阻塞式线程安全列表/06-04-使用按优先级排序的阻塞式线程安全列表.iml
================================================
================================================
FILE: 06-04-使用按优先级排序的阻塞式线程安全列表/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Event;
import com.concurrency.task.Task;
import java.util.concurrent.PriorityBlockingQueue;
public class Main {
public static void main(String[] args) {
// 存储事件的优先级队列
PriorityBlockingQueue queue = new PriorityBlockingQueue<>();
// 存储5个线程对象的数组
Thread taskThreads[] = new Thread[5];
// 创建5个线程运行5个任务,每个任务创建1000事件对象
for (int i = 0; i < taskThreads.length; i++) {
Task task = new Task(i, queue);
taskThreads[i] = new Thread(task);
}
// 启动5个线程
for (Thread taskThread : taskThreads) {
taskThread.start();
}
// 等待5个线程完成
for (Thread taskThread : taskThreads) {
try {
taskThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 输出事件信息
System.out.printf("Main: Queue Size: %d\n", queue.size());
for (int i = 0; i < taskThreads.length * 1000; i++) {
Event event = queue.poll();
System.out.printf("Thread %s: Priority %d\n", event.getThread(), event.getPriority());
}
System.out.printf("Main: Queue Size: %d\n", queue.size());
System.out.printf("Main: End of the program\n");
}
}
================================================
FILE: 06-04-使用按优先级排序的阻塞式线程安全列表/src/com/concurrency/task/Event.java
================================================
package com.concurrency.task;
import com.sun.istack.internal.NotNull;
/**
* 事件类,存储一个件事的属性,它包括一个事件的优先级,这个类实现了Comparable接口的方法,
* 用来确定哪个事件对象的优先级更高
*/
public class Event implements Comparable {
/**
* 线程编号
*/
private int thread;
/**
* 线程优先级
*/
private int priority;
/**
* 构造构造,用于初始化属性
*
* @param thread 产生事件的线程编号
* @param priority 事件的优先级
*/
public Event(int thread, int priority) {
this.thread = thread;
this.priority = priority;
}
/**
* 获取线程编号
*
* @return 线程编号
*/
public int getThread() {
return thread;
}
/**
* 获取线程优先级
*
* @return 线程优先级
*/
public int getPriority() {
return priority;
}
/**
* 比较那个线程的优先级更高
*/
@Override
public int compareTo(Event e) {
if (this.priority > e.getPriority()) {
return -1;
} else if (this.priority < e.getPriority()) {
return 1;
} else {
return 0;
}
}
}
================================================
FILE: 06-04-使用按优先级排序的阻塞式线程安全列表/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.concurrent.PriorityBlockingQueue;
/**
* 任务对象,生成1000个事件,并且将其存放在一个优先队列中
*/
public class Task implements Runnable {
/**
* 任务编号
*/
private int id;
/**
* 存储事件的优先队列
*/
private PriorityBlockingQueue queue;
/**
* 构造函数,初始化属性
*
* @param id 任务编号
* @param queue 存储事件的优先队列
*/
public Task(int id, PriorityBlockingQueue queue) {
this.id = id;
this.queue = queue;
}
/**
* 核心方法,生成1000个事件,并且将其存放在一个优先队列中
*/
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
Event event = new Event(id, i);
queue.add(event);
}
}
}
================================================
FILE: 06-05-使用带有延迟元素的线程安全列表/06-05-使用带有延迟元素的线程安全列表.iml
================================================
================================================
FILE: 06-05-使用带有延迟元素的线程安全列表/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Event;
import com.concurrency.task.Task;
import java.util.Date;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
// 存储事件的延迟队列
DelayQueue queue = new DelayQueue<>();
// 线程数组
Thread threads[] = new Thread[5];
// 创建5个任务对象,并且放在不同的线程中去执行
for (int i = 0; i < threads.length; i++) {
Task task = new Task(i + 1, queue);
threads[i] = new Thread(task);
}
// 启动线程
for (Thread thread : threads) {
thread.start();
}
// 等待5个任务的完成
for (Thread thread : threads) {
thread.join();
}
// 输出结果
do {
int counter = 0;
Event event;
do { // 取队列中的所有数据
event = queue.poll();
if (event != null) {
counter++;
}
} while (event != null);
System.out.printf("At %s you have read %d events\n", new Date(), counter);
TimeUnit.MILLISECONDS.sleep(500);
} while (queue.size() > 0);
}
}
================================================
FILE: 06-05-使用带有延迟元素的线程安全列表/src/com/concurrency/task/Event.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* 事件类,实现了延迟队列接口
*/
public class Event implements Delayed {
/**
* 激活事件的时间
*/
private Date startDate;
/**
* 构造函数
*
* @param startDate 激活事件的时间
*/
public Event(Date startDate) {
this.startDate = startDate;
}
/**
* 比较两个事件
*/
@Override
public int compareTo(Delayed o) {
long result = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
if (result < 0) {
return -1;
} else if (result > 0) {
return 1;
}
return 0;
}
/**
* 返回离激活时间还剩余的毫秒数
*/
@Override
public long getDelay(TimeUnit unit) {
Date now = new Date();
long diff = startDate.getTime() - now.getTime();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
}
================================================
FILE: 06-05-使用带有延迟元素的线程安全列表/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.DelayQueue;
/**
* 任务类,其事件存储在一个延迟队列中
*/
public class Task implements Runnable {
/**
* 任务编号
*/
private int id;
/**
* 存储事件的任务队列
*/
private DelayQueue queue;
/**
* 构造函数,初始化属性
*
* @param id 任务编号
* @param queue 存储事件的任务队列
*/
public Task(int id, DelayQueue queue) {
this.id = id;
this.queue = queue;
}
/**
* 核心方法,产生100事件,每个事件有相同的激活时间,将这些事件存储在延迟队列中
*/
@Override
public void run() {
Date now = new Date();
Date delay = new Date();
delay.setTime(now.getTime() + (id * 1000));
System.out.printf("Thread %s: %s\n", id, delay);
for (int i = 0; i < 100; i++) {
Event event = new Event(delay);
queue.add(event);
}
}
}
================================================
FILE: 06-06-使用线程安全可遍历映射/06-06-使用线程安全可遍历映射.iml
================================================
================================================
FILE: 06-06-使用线程安全可遍历映射/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Task;
import com.concurrency.utils.Contact;
import java.util.Map;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
public class Main {
public static void main(String[] args) {
// 创建一个可遍历的映射对象
ConcurrentSkipListMap map;
map = new ConcurrentSkipListMap<>();
// 创建长度为25的线程数组
Thread threads[] = new Thread[25];
int counter = 0;
// 在25个不同的线程中执行25个任务
for (char i = 'A'; i < 'Z'; i++) {
Task task = new Task(map, String.valueOf(i));
threads[counter] = new Thread(task);
threads[counter].start();
counter++;
}
// 等待任务执行完成
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 输出映射的大小
System.out.printf("Main: Size of the map: %d\n", map.size());
// 保存映射条目的对象
Map.Entry element;
// 保存联系人的对象
Contact contact;
element = map.firstEntry();
contact = element.getValue();
System.out.printf("Main: First Entry: %s: %s\n", contact.getName(), contact.getPhone());
// 输出最后一个映射条目
element = map.lastEntry();
contact = element.getValue();
System.out.printf("Main: Last Entry: %s: %s\n", contact.getName(), contact.getPhone());
// 输出映射的字集
System.out.printf("Main: Submap from A1996 to B1002: \n");
ConcurrentNavigableMap submap = map.subMap("A1996", "B1002");
do {
element = submap.pollFirstEntry();
if (element != null) {
contact = element.getValue();
System.out.printf("%s: %s\n", contact.getName(), contact.getPhone());
}
} while (element != null);
}
}
================================================
FILE: 06-06-使用线程安全可遍历映射/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import com.concurrency.utils.Contact;
import java.util.concurrent.ConcurrentSkipListMap;
/**
* 任务类,将联系人存储在一个可遍历的图中
*/
public class Task implements Runnable {
/**
* 存储联系人的可遍历的映射
*/
private ConcurrentSkipListMap map;
/**
* 任务编号
*/
private String id;
/**
* 构造函数,初始化属性
*
* @param map 存储联系人的可遍历的映射
* @param id 任务编号
*/
public Task(ConcurrentSkipListMap map, String id) {
this.id = id;
this.map = map;
}
/**
* 核心方法,产生1000个联系人,并且交它们存储在一个可遍历的映射中
*/
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
Contact contact = new Contact(id, String.valueOf(i + 1000));
map.put(id + contact.getPhone(), contact);
}
}
}
================================================
FILE: 06-06-使用线程安全可遍历映射/src/com/concurrency/utils/Contact.java
================================================
package com.concurrency.utils;
/**
* 联系人类
*/
public class Contact {
/**
* 联系人的名称
*/
private String name;
/**
* 联系人的电话
*/
private String phone;
/**
* 构造函数
*
* @param name 联系人的名称
* @param phone 联系人的电话
*/
public Contact(String name, String phone) {
this.name = name;
this.phone = phone;
}
/**
* 获取 联系人的名称
*
* @return 联系人的名称
*/
public String getName() {
return name;
}
/**
* 获取联系人的电话
*
* @return 联系人的电话
*/
public String getPhone() {
return phone;
}
}
================================================
FILE: 06-07-生成并发随机数/06-07-生成并发随机数.iml
================================================
================================================
FILE: 06-07-生成并发随机数/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.TaskLocalRandom;
public class Main {
public static void main(String[] args) {
// 长度为3的线程数组
Thread threads[] = new Thread[3];
// 创建线程并且运行任务
for (int i = 0; i < threads.length; i++) {
TaskLocalRandom task = new TaskLocalRandom();
threads[i] = new Thread(task);
threads[i].start();
}
}
}
================================================
FILE: 06-07-生成并发随机数/src/com/concurrency/task/TaskLocalRandom.java
================================================
package com.concurrency.task;
import java.util.concurrent.ThreadLocalRandom;
/**
* 产生随机数的任务类
*/
public class TaskLocalRandom implements Runnable {
/**
* 构造函数,初始化当前类的随机数生成对象
*/
public TaskLocalRandom() {
ThreadLocalRandom.current();
}
/**
* 核心方法,生成一个[0, 10)的随机数
*/
@Override
public void run() {
String name = Thread.currentThread().getName();
for (int i = 0; i < 10; i++) {
System.out.printf("%s: %d\n", name, ThreadLocalRandom.current().nextInt(10));
}
}
}
================================================
FILE: 06-08-使用原子变量/06-08-使用原子变量.iml
================================================
================================================
FILE: 06-08-使用原子变量/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Account;
import com.concurrency.task.Bank;
import com.concurrency.task.Company;
public class Main {
public static void main(String[] args) {
// 创建一个帐户对象
Account account = new Account();
// 初始化帐户余额
account.setBalance(1000);
// 创建一个公司对象,并且将公司对象放到线程中去运行
Company company = new Company(account);
Thread companyThread = new Thread(company);
// 创建一个银行对象,并且将银行对象放到线程中去运行
Bank bank = new Bank(account);
Thread bankThread = new Thread(bank);
// 输出帐户对象最初的信息
System.out.printf("Account : Initial Balance: %d\n", account.getBalance());
// 启动线程
companyThread.start();
bankThread.start();
try {
// 等待线程完成
companyThread.join();
bankThread.join();
// 输出余额
System.out.printf("Account : Final Balance: %d\n", account.getBalance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 06-08-使用原子变量/src/com/concurrency/task/Account.java
================================================
package com.concurrency.task;
import java.util.concurrent.atomic.AtomicLong;
/**
* 帐户类
*/
public class Account {
/**
* 帐户余额
*/
private AtomicLong balance;
public Account() {
balance = new AtomicLong();
}
/**
*/
/**
* 获取帐户余额
*
* @return 帐户余额
*/
public long getBalance() {
return balance.get();
}
/**
* 设置帐户余额
*
* @param balance 帐户余额
*/
public void setBalance(long balance) {
this.balance.set(balance);
}
/**
* 增加余额
*
* @param amount 增加的数目
*/
public void addAmount(long amount) {
this.balance.getAndAdd(amount);
}
/**
* 减少余额
*
* @param amount 减少的数目
*/
public void subtractAmount(long amount) {
this.balance.getAndAdd(-amount);
}
}
================================================
FILE: 06-08-使用原子变量/src/com/concurrency/task/Bank.java
================================================
package com.concurrency.task;
/**
* 银行帐户类,模拟从一个帐户上取钱
*/
public class Bank implements Runnable {
/**
* 帐户对象
*/
private Account account;
/**
* 构造函数,初始化帐户属性
*
* @param account 帐户对象
*/
public Bank(Account account) {
this.account = account;
}
/**
* 核心方法,取钱
*/
@Override
public void run() {
for (int i = 0; i < 10; i++) {
account.subtractAmount(1000);
}
}
}
================================================
FILE: 06-08-使用原子变量/src/com/concurrency/task/Company.java
================================================
package com.concurrency.task;
/**
* 公司类,模拟向一个帐户存钱
*/
public class Company implements Runnable {
/**
* 帐户对象
*/
private Account account;
/**
* 构造函数,初始化帐户属性
*
* @param account 帐户对象
*/
public Company(Account account) {
this.account = account;
}
/**
* 核心方法,存钱
*/
@Override
public void run() {
for (int i = 0; i < 10; i++) {
account.addAmount(1000);
}
}
}
================================================
FILE: 06-09-使用原子数组/06-09-使用原子数组.iml
================================================
================================================
FILE: 06-09-使用原子数组/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Decrementer;
import com.concurrency.task.Incrementer;
import java.util.concurrent.atomic.AtomicIntegerArray;
public class Main {
public static void main(String[] args) {
// 线程个数
final int THREADS = 100;
// 原子数组对象,它有1000个元素
AtomicIntegerArray vector = new AtomicIntegerArray(1000);
// 创建一个加法器对象
Incrementer incrementer = new Incrementer(vector);
// 创建一个减法器对象
Decrementer decrementer = new Decrementer(vector);
// 创建并且执行100个加法线程和100个减法线程
Thread threadIncrementer[] = new Thread[THREADS];
Thread threadDecrementer[] = new Thread[THREADS];
for (int i = 0; i < THREADS; i++) {
threadIncrementer[i] = new Thread(incrementer);
threadDecrementer[i] = new Thread(decrementer);
threadIncrementer[i].start();
threadDecrementer[i].start();
}
// 等待所有的任务完成
for (int i = 0; i < THREADS; i++) {
try {
threadIncrementer[i].join();
threadDecrementer[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 输出不为0的元素
for (int i = 0; i < vector.length(); i++) {
if (vector.get(i) != 0) {
System.out.println("Vector[" + i + "] : " + vector.get(i));
}
}
System.out.println("Main: End of the example");
}
}
================================================
FILE: 06-09-使用原子数组/src/com/concurrency/task/Decrementer.java
================================================
package com.concurrency.task;
import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* 减法器,将数组中的每元素减少指定个单位
*/
public class Decrementer implements Runnable {
/**
* 要执行减法的数组
*/
private AtomicIntegerArray vector;
/**
* 构造函数
*
* @param vector 要执行减法的数组
*/
public Decrementer(AtomicIntegerArray vector) {
this.vector = vector;
}
/**
* 核心方法, 将数组中的每元素减少指定个单位
*/
@Override
public void run() {
for (int i = 0; i < vector.length(); i++) {
vector.getAndDecrement(i);
}
}
}
================================================
FILE: 06-09-使用原子数组/src/com/concurrency/task/Incrementer.java
================================================
package com.concurrency.task;
import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* 加法器,将数组中的每元素增加指定个单位
*/
public class Incrementer implements Runnable {
/**
* 要执行加法的数组
*/
private AtomicIntegerArray vector;
/**
* 构造函数
*
* @param vector 要执行加法的数组
*/
public Incrementer(AtomicIntegerArray vector) {
this.vector = vector;
}
/**
* 核心方法,将数组中的每元素增加指定个单位
*/
@Override
public void run() {
for (int i = 0; i < vector.length(); i++) {
vector.getAndIncrement(i);
}
}
}
================================================
FILE: 07-02-定制ThreadPoolExecutor类/07-02-定制ThreadPoolExecutor类.iml
================================================
================================================
FILE: 07-02-定制ThreadPoolExecutor类/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.executor.MyExecutor;
import com.concurrency.task.SleepTwoSecondsTask;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建一个定制的线程执行器
MyExecutor myExecutor = new MyExecutor(2, 4, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque());
// 创建一个队列来存存储任务的执行结果
List> results = new ArrayList<>();
// 创建并且提交10个任务
for (int i = 0; i < 10; i++) {
SleepTwoSecondsTask task = new SleepTwoSecondsTask();
Future result = myExecutor.submit(task);
results.add(result);
}
// 获取前5个的执行结果
for (int i = 0; i < 5; i++) {
try {
String result = results.get(i).get();
System.out.printf("Main: Result for Task %d : %s\n", i, result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
// 关闭线执行器
myExecutor.shutdown();
// 获取后5个的执行结果
for (int i = 5; i < 10; i++) {
try {
String result = results.get(i).get();
System.out.printf("Main: Result for Task %d : %s\n", i, result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
// 等待执行器执行完
try {
myExecutor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出信息,表示整个程序运行结束
System.out.printf("Main: End of the program.\n");
}
}
================================================
FILE: 07-02-定制ThreadPoolExecutor类/src/com/concurrency/executor/MyExecutor.java
================================================
package com.concurrency.executor;
import java.util.Date;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* չִ̳߳࣬ʵִֶܡ
*/
public class MyExecutor extends ThreadPoolExecutor {
/**
* û洢ƣ̵߳hashCodeַʽʼִеʱ
*/
private ConcurrentHashMap startTimes;
/**
* 캯
*
* @param corePoolSize ̳߳С߳Ŀ
* @param maximumPoolSize ̳߳߳Ŀ
* @param keepAliveTime ߳Ŀʱ
* @param unit ʱʱ䵥λ
* @param workQueue ύʹõĶ
*/
public MyExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
startTimes = new ConcurrentHashMap<>();
}
/**
* ִִУ̳߳صϢ
*/
@Override
public void shutdown() {
System.out.printf("MyExecutor: Going to shutdown.\n");
System.out.printf("MyExecutor: Executed tasks: %d\n", getCompletedTaskCount());
System.out.printf("MyExecutor: Running tasks: %d\n", getActiveCount());
System.out.printf("MyExecutor: Pending tasks: %d\n", getQueue().size());
super.shutdown();
}
/**
* ̳߳صִУ ̳߳صϢ
*/
@Override
public List shutdownNow() {
System.out.printf("MyExecutor: Going to immediately shutdown.\n");
System.out.printf("MyExecutor: Executed tasks: %d\n", getCompletedTaskCount());
System.out.printf("MyExecutor: Running tasks: %d\n", getActiveCount());
System.out.printf("MyExecutor: Pending tasks: %d\n", getQueue().size());
return super.shutdownNow();
}
/**
* ִ֮߳ǰõķʱǴӡ߳Ϣʹ洢߳Ϣ
*/
@Override
protected void beforeExecute(Thread t, Runnable r) {
System.out.printf("MyExecutor: A task is beginning: %s : %s\n", t.getName(), r.hashCode());
startTimes.put(String.valueOf(r.hashCode()), new Date());
}
/**
* ִ߳ɺִеķ̵߳Ϣִеʱ
*/
@Override
protected void afterExecute(Runnable r, Throwable t) {
Future> result = (Future>) r;
try {
System.out.printf("*********************************\n");
System.out.printf("MyExecutor: A task is finishing.\n");
System.out.printf("MyExecutor: Result: %s\n", result.get());
Date startDate = startTimes.remove(String.valueOf(r.hashCode()));
Date finishDate = new Date();
long diff = finishDate.getTime() - startDate.getTime();
System.out.printf("MyExecutor: Duration: %d\n", diff);
System.out.printf("*********************************\n");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 07-02-定制ThreadPoolExecutor类/src/com/concurrency/task/SleepTwoSecondsTask.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
*
*/
public class SleepTwoSecondsTask implements Callable {
/**
* ʱַ
*/
public String call() throws Exception {
TimeUnit.SECONDS.sleep(2);
return new Date().toString();
}
}
================================================
FILE: 07-03-基于优先级的Executor类/07-03-基于优先级的Executor类.iml
================================================
================================================
FILE: 07-03-基于优先级的Executor类/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.MyPriorityTask;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// ִ߳
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 1,
TimeUnit.SECONDS, new PriorityBlockingQueue());
// ִ4
for (int i = 0; i < 4; i++) {
MyPriorityTask task = new MyPriorityTask("Task " + i, i);
executor.execute(task);
}
// ߳1S
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// ִ4
for (int i = 4; i < 8; i++) {
MyPriorityTask task = new MyPriorityTask("Task " + i, i);
executor.execute(task);
}
// رִ
executor.shutdown();
// ен
try {
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Ϣʾн
System.out.printf("Main: End of the program.\n");
}
}
================================================
FILE: 07-03-基于优先级的Executor类/src/com/concurrency/task/MyPriorityTask.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
/**
* ָȼ
*/
public class MyPriorityTask implements Runnable, Comparable {
/**
* ȼ
*/
private int priority;
/**
*
*/
private String name;
/**
* 캯
*
* @param name
* @param priority ȼ
*/
public MyPriorityTask(String name, int priority) {
this.name = name;
this.priority = priority;
}
/**
* ȡȼ
*
* @return ȼ
*/
public int getPriority() {
return priority;
}
/**
* ȽϷһбȽ
*/
@Override
public int compareTo(MyPriorityTask o) {
if (this.getPriority() < o.getPriority()) {
return 1;
}
if (this.getPriority() > o.getPriority()) {
return -1;
}
return 0;
}
/**
* ӣϢӣ
*/
@Override
public void run() {
System.out.printf("MyPriorityTask: %s Priority : %d\n", name, priority);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 07-04-实现ThreadFactory接口生成定制线程/07-04-实现ThreadFactory接口生成定制线程.iml
================================================
================================================
FILE: 07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.MyTask;
import com.concurrency.task.MyThreadFactory;
public class Main {
public static void main(String[] args) throws Exception {
// һ̹߳
MyThreadFactory myFactory = new MyThreadFactory("MyThreadFactory");
// һ
MyTask task = new MyTask();
// ʹԶ̹߳һµ߳
Thread thread = myFactory.newThread(task);
// ʼִ߳
thread.start();
// ȴִ߳н
thread.join();
// ߳Ϣ
System.out.printf("Main: Thread information.\n");
System.out.printf("%s\n", thread);
System.out.printf("Main: End of the example.\n");
}
}
================================================
FILE: 07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyTask.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
/**
* Զ
*/
public class MyTask implements Runnable {
/**
*
*/
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThread.java
================================================
package com.concurrency.task;
import java.util.Date;
/**
* Զ߳
*/
public class MyThread extends Thread {
// ̴߳ʱ
private Date creationDate;
// ߿ʼִеʱ
private Date startDate;
// ִ߳еʱ
private Date finishDate;
/**
* 캯
*
* @param target ִе
* @param name ̵߳
*/
public MyThread(Runnable target, String name) {
super(target, name);
setCreationDate();
}
/**
* ¼߳еĿʼͽʱ
*/
@Override
public void run() {
setStartDate();
super.run();
setFinishDate();
}
/**
* ̴߳ʱ
*/
public void setCreationDate() {
creationDate = new Date();
}
/**
* ߳̿ʼִеʱ
*/
public void setStartDate() {
startDate = new Date();
}
/**
* ִ߳̽еʱ
*/
public void setFinishDate() {
finishDate = new Date();
}
/**
* ִ߳еʱ
*
* @return ִ߳еʱ
*/
public long getExecutionTime() {
return finishDate.getTime() - startDate.getTime();
}
/**
* ߳Ϣ
*/
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(getName());
buffer.append(": ");
buffer.append(" Creation Date: ");
buffer.append(creationDate);
buffer.append(" : Running time: ");
buffer.append(getExecutionTime());
buffer.append(" Milliseconds.");
return buffer.toString();
}
}
================================================
FILE: 07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThreadFactory.java
================================================
package com.concurrency.task;
import java.util.concurrent.ThreadFactory;
/**
* Զ̹߳
*/
public class MyThreadFactory implements ThreadFactory {
// ¼е߳Ŀ
private int counter;
// ̵߳ǰ
private String prefix;
/**
* 캯
*
* @param prefix ߳ǰ
*/
public MyThreadFactory(String prefix) {
this.prefix = prefix;
counter = 1;
}
/**
* ̵߳Ĺ
*/
@Override
public Thread newThread(Runnable r) {
MyThread myThread = new MyThread(r, prefix + "-" + counter);
counter++;
return myThread;
}
}
================================================
FILE: 07-05-在Executro对象中使用ThreadFactory/07-05-在Executro对象中使用ThreadFactory.iml
================================================
================================================
FILE: 07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.MyTask;
import com.concurrency.task.MyThreadFactory;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
// һԶ̹߳
MyThreadFactory threadFactory=new MyThreadFactory("MyThreadFactory");
// һִ̻߳IJ̹߳
ExecutorService executor=Executors.newCachedThreadPool(threadFactory);
// һԶ
MyTask task=new MyTask();
// ύִ
executor.submit(task);
// رִ
executor.shutdown();
// ȴִен
executor.awaitTermination(1, TimeUnit.DAYS);
// ϢѾ
System.out.printf("Main: End of the program.\n");
}
}
================================================
FILE: 07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyTask.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
/**
* Զ
*/
public class MyTask implements Runnable {
/**
*
*/
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
================================================
FILE: 07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThread.java
================================================
package com.concurrency.task;
import java.util.Date;
/**
* Զ߳
*/
public class MyThread extends Thread {
// ̴߳ʱ
private Date creationDate;
// ߿ʼִеʱ
private Date startDate;
// ִ߳еʱ
private Date finishDate;
/**
* 캯
*
* @param target ִе
* @param name ̵߳
*/
public MyThread(Runnable target, String name) {
super(target, name);
setCreationDate();
}
/**
* ¼߳еĿʼͽʱ
*/
@Override
public void run() {
setStartDate();
super.run();
setFinishDate();
}
/**
* ̴߳ʱ
*/
public void setCreationDate() {
creationDate = new Date();
}
/**
* ߳̿ʼִеʱ
*/
public void setStartDate() {
startDate = new Date();
}
/**
* ִ߳̽еʱ
*/
public void setFinishDate() {
finishDate = new Date();
}
/**
* ִ߳еʱ
*
* @return ִ߳еʱ
*/
public long getExecutionTime() {
return finishDate.getTime() - startDate.getTime();
}
/**
* ߳Ϣ
*/
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(getName());
buffer.append(": ");
buffer.append(" Creation Date: ");
buffer.append(creationDate);
buffer.append(" : Running time: ");
buffer.append(getExecutionTime());
buffer.append(" Milliseconds.");
return buffer.toString();
}
}
================================================
FILE: 07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThreadFactory.java
================================================
package com.concurrency.task;
import java.util.concurrent.ThreadFactory;
/**
* Զ̹߳
*/
public class MyThreadFactory implements ThreadFactory {
// ¼е߳Ŀ
private int counter;
// ̵߳ǰ
private String prefix;
/**
* 캯
*
* @param prefix ߳ǰ
*/
public MyThreadFactory(String prefix) {
this.prefix = prefix;
counter = 1;
}
/**
* ̵߳Ĺ
*/
@Override
public Thread newThread(Runnable r) {
MyThread myThread = new MyThread(r, prefix + "-" + counter);
counter++;
return myThread;
}
}
================================================
FILE: 07-06-定制运行在线程池中的任务/07-06-定制运行在线程池中的任务.iml
================================================
================================================
FILE: 07-06-定制运行在线程池中的任务/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.MyScheduledThreadPoolExecutor;
import com.concurrency.task.Task;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
// һԶĵִ̳߳
MyScheduledThreadPoolExecutor executor = new MyScheduledThreadPoolExecutor(2);
// һ
Task task = new Task();
// ʼִеʱ
System.out.printf("Main: %s\n", new Date());
// ִзһһִ
executor.schedule(task, 1, TimeUnit.SECONDS);
// ߳3
TimeUnit.SECONDS.sleep(3);
// һ
task = new Task();
// ʼִеʱ
System.out.printf("Main: %s\n", new Date());
// һִһִУҷÿִһ
executor.scheduleAtFixedRate(task, 1, 3, TimeUnit.SECONDS);
// ߳10
TimeUnit.SECONDS.sleep(10);
// رִ
executor.shutdown();
// ִн
executor.awaitTermination(1, TimeUnit.DAYS);
// Ϣ֪ͨн
System.out.printf("Main: End of the program.\n");
}
}
================================================
FILE: 07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledTask.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.Delayed;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Զ߶࣬һV
*
* @param
*/
public class MyScheduledTask extends FutureTask implements RunnableScheduledFuture {
// ڴ洢ɵȵ
private RunnableScheduledFuture task;
// ɵȵִ̳߳
private ScheduledThreadPoolExecutor executor;
// ִеʱ
private long period;
// ʼִеʱ
private long startDate;
/**
* 캯
*
* @param runnable ύĿִе
* @param result صĽ
* @param task ִrunnable
* @param executor ִtaskִ
*/
public MyScheduledTask(Runnable runnable, V result, RunnableScheduledFuture task, ScheduledThreadPoolExecutor executor) {
super(runnable, result);
this.task = task;
this.executor = executor;
}
/**
* һҪִеʣʱ䣬ӳͷӳʱ䣬
* ؿʼʱ͵ǰʱIJֵ
*
* @param unit ӳٵʱ䵥λ
*/
@Override
public long getDelay(TimeUnit unit) {
if (!isPeriodic()) {
return task.getDelay(unit);
} else {
if (startDate == 0) {
return task.getDelay(unit);
} else {
Date now = new Date();
long delay = startDate - now.getTime();
return unit.convert(delay, TimeUnit.MILLISECONDS);
}
}
}
/**
* ȽϷ
*/
@Override
public int compareTo(Delayed o) {
return task.compareTo(o);
}
/**
* жǷ
*/
@Override
public boolean isPeriodic() {
return task.isPeriodic();
}
/**
*
*/
@Override
public void run() {
// ִûйر
if (isPeriodic() && (!executor.isShutdown())) {
// ¿ʼʱ䣬ͬʱٴ
Date now = new Date();
startDate = now.getTime() + period;
executor.getQueue().add(this);
}
// Ϣ
System.out.printf("Pre-MyScheduledTask: %s\n", new Date());
System.out.printf("MyScheduledTask: Is Periodic: %s\n", isPeriodic());
super.runAndReset();
System.out.printf("Post-MyScheduledTask: %s\n", new Date());
}
/**
* ʱ
*
* @param period ʱ
*/
public void setPeriod(long period) {
this.period = period;
}
}
================================================
FILE: 07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledThreadPoolExecutor.java
================================================
package com.concurrency.task;
import java.util.concurrent.RunnableScheduledFuture;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Զ̳߳ص
*/
public class MyScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
/**
* 캯
*
* @param corePoolSize ̳߳ٱ
*/
public MyScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize);
}
/**
* װηһRunnableScheduledFutureתMyScheduledTask
*/
@Override
protected RunnableScheduledFuture decorateTask(Runnable runnable,
RunnableScheduledFuture task) {
MyScheduledTask myTask = new MyScheduledTask(runnable, null, task, this);
return myTask;
}
/**
* ִڵȵķ
*/
@Override
public ScheduledFuture> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit) {
// ʹóķȥ
ScheduledFuture> task = super.scheduleAtFixedRate(command, initialDelay, period, unit);
MyScheduledTask> myTask = (MyScheduledTask>) task;
myTask.setPeriod(TimeUnit.MILLISECONDS.convert(period, unit));
return task;
}
}
================================================
FILE: 07-06-定制运行在线程池中的任务/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
/**
* Զ
*/
public class Task implements Runnable {
/**
*
*/
@Override
public void run() {
System.out.printf("Task: Begin.\n");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Task: End.\n");
}
}
================================================
FILE: 07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程.iml
================================================
================================================
FILE: 07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.MyRecursiveTask;
import com.concurrency.task.MyWorkerThreadFactory;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
// һ̹߳
MyWorkerThreadFactory factory = new MyWorkerThreadFactory();
// һFork/Join
ForkJoinPool pool = new ForkJoinPool(4, factory, null, false);
// ʼһ
int array[] = new int[100000];
for (int i = 0; i < array.length; i++) {
array[i] = 1;
}
// һִм
MyRecursiveTask task = new MyRecursiveTask(array, 0, array.length);
// ύfork/join
pool.execute(task);
// ִ
task.join();
// رFork/Join
pool.shutdown();
// ен
pool.awaitTermination(1, TimeUnit.DAYS);
// ִеĽ
System.out.printf("Main: Result: %d\n", task.get());
// Ϣʾн
System.out.printf("Main: End of the program\n");
}
}
================================================
FILE: 07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyRecursiveTask.java
================================================
package com.concurrency.task;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
/**
* Զݹ
*/
public class MyRecursiveTask extends RecursiveTask {
private static final long serialVersionUID = 1L;
//
private int array[];
// ʼͽλ
private int start, end;
/**
* 캯ʼ
*
* @param array
* @param start ʼλ
* @param end Ľλ
*/
public MyRecursiveTask(int array[], int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
/**
* мĿ100ͻִ
*/
@Override
protected Integer compute() {
Integer ret;
MyWorkerThread thread = (MyWorkerThread) Thread.currentThread();
thread.addTask();
if (end - start > 100) {
int mid = (start + end) / 2;
MyRecursiveTask task1 = new MyRecursiveTask(array, start, mid);
MyRecursiveTask task2 = new MyRecursiveTask(array, mid, end);
invokeAll(task1, task2);
ret = addResults(task1, task2);
} else {
int add = 0;
for (int i = start; i < end; i++) {
add += array[i];
}
ret = new Integer(add);
}
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return ret;
}
/**
* 鲢Ľ
*
* @param task1 First task
* @param task2 Second task
* @return The sum of the results of the two tasks
*/
private Integer addResults(MyRecursiveTask task1, MyRecursiveTask task2) {
int value;
try {
value = task1.get().intValue() + task2.get().intValue();
} catch (InterruptedException e) {
e.printStackTrace();
value = 0;
} catch (ExecutionException e) {
e.printStackTrace();
value = 0;
}
return new Integer(value);
}
}
================================================
FILE: 07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThread.java
================================================
package com.concurrency.task;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
/**
* Զ幤߳
*/
public class MyWorkerThread extends ForkJoinWorkerThread {
// ÿִ߳е
private static ThreadLocal taskCounter = new ThreadLocal<>();
/**
* 캯
*
* @param pool ֺϳض
*/
protected MyWorkerThread(ForkJoinPool pool) {
super(pool);
}
/**
* һFork/Joinܵ߳̿ʼִʱеãʼ
*/
@Override
protected void onStart() {
super.onStart();
System.out.printf("MyWorkerThread %d: Initializing task counter.\n", getId());
taskCounter.set(0);
}
/**
* һFork/Joinִܵ߳̽ʱеãִ߳е
*/
@Override
protected void onTermination(Throwable exception) {
System.out.printf("MyWorkerThread %d: %d\n", getId(), taskCounter.get());
super.onTermination(exception);
}
/**
*
*/
public void addTask() {
int counter = taskCounter.get().intValue();
counter++;
taskCounter.set(counter);
}
}
================================================
FILE: 07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThreadFactory.java
================================================
package com.concurrency.task;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
/**
* ԶFork/Join̹߳
*/
public class MyWorkerThreadFactory implements ForkJoinWorkerThreadFactory {
/**
* ΪFork/Joinܴһ߳
*
* @param pool ߳̽Ҫִе̳߳
* @return һԶĹ̶߳
*/
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
return new MyWorkerThread(pool);
}
}
================================================
FILE: 07-08-定制运行在Fork-Join框架中的任务/07-08-定制运行在Fork-Join框架中的任务.iml
================================================
================================================
FILE: 07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Task;
import java.util.concurrent.ForkJoinPool;
public class Main {
public static void main(String[] args) throws Exception {
int array[] = new int[10000];
// һִг
ForkJoinPool pool = new ForkJoinPool();
// һ
Task task = new Task("Task", array, 0, array.length);
// ύִг
pool.invoke(task);
// رִг
pool.shutdown();
// Ϣִн
System.out.printf("Main: End of the program.\n");
}
}
================================================
FILE: 07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/MyWorkerTask.java
================================================
package com.concurrency.task;
import java.util.Date;
import java.util.concurrent.ForkJoinTask;
/**
* Զ幤ֵ
*/
public abstract class MyWorkerTask extends ForkJoinTask {
private static final long serialVersionUID = 1L;
//
private String name;
/**
* 캯ʼ
*
* @param name
*/
public MyWorkerTask(String name) {
this.name = name;
}
/**
* ȡִнִأ
*/
@Override
public Void getRawResult() {
return null;
}
/**
* ý
*/
@Override
protected void setRawResult(Void value) {
}
/**
* ִ
*/
@Override
protected boolean exec() {
Date startDate = new Date();
compute();
Date finishDate = new Date();
long diff = finishDate.getTime() - startDate.getTime();
System.out.printf("MyWorkerTask: %s : %d Milliseconds to complete.\n", name, diff);
return true;
}
/**
* ȡ
*
* @return
*/
public String getName() {
return name;
}
/**
* ģ巽ȴʵ
*/
protected abstract void compute();
}
================================================
FILE: 07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
/**
* Զ
*/
public class Task extends MyWorkerTask {
private static final long serialVersionUID = 1L;
// Ҫ
private int array[];
// ʼλ
private int start;
// λã
private int end;
/**
* 캯ʼ
*
* @param name
* @param array
* @param start ʼλ
* @param end λ
*/
public Task(String name, int array[], int start, int end) {
super(name);
this.array = array;
this.start = start;
this.end = end;
}
/**
* ÷ҪԪظ¦100ͷֳд
*/
@Override
protected void compute() {
if (end - start > 100) {
int mid = (end + start) / 2;
Task task1 = new Task(this.getName() + "1", array, start, mid);
Task task2 = new Task(this.getName() + "2", array, mid, end);
invokeAll(task1, task2);
} else {
for (int i = start; i < end; i++) {
array[i]++;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
================================================
FILE: 07-09-现实定制Lock类/07-09-现实定制Lock类.iml
================================================
================================================
FILE: 07-09-现实定制Lock类/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.MyLock;
import com.concurrency.task.Task;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// һԶ
MyLock lock = new MyLock();
// 10
for (int i = 0; i < 10; i++) {
Task task = new Task("Task-" + i, lock);
Thread thread = new Thread(task);
thread.start();
}
// ߳ͼȡ
boolean value;
do {
try {
value = lock.tryLock(1, TimeUnit.SECONDS);
if (!value) {
System.out.printf("Main: Trying to get the Lock\n");
}
} catch (InterruptedException e) {
e.printStackTrace();
value = false;
}
} while (!value);
// ߳ͷ
System.out.printf("Main: Got the lock\n");
lock.unlock();
// Ϣн
System.out.printf("Main: End of the program\n");
}
}
================================================
FILE: 07-09-现实定制Lock类/src/com/concurrency/task/MyAbstractQueuedSynchronizer.java
================================================
package com.concurrency.task;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
/**
* Զͬ
*/
public class MyAbstractQueuedSynchronizer extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 1L;
// ԭӱ洢״̬0У1æ
private AtomicInteger state;
/**
* 캯
*/
public MyAbstractQueuedSynchronizer() {
state = new AtomicInteger(0);
}
/**
* ȡ
*
* @param arg ڱвʹã
* @return trueȡfalseδȡ
*/
@Override
protected boolean tryAcquire(int arg) {
return state.compareAndSet(0, 1);
}
/**
* ͷ
*
* @param arg ͷвʹã
* @return trueɹfalseʧ
*/
@Override
protected boolean tryRelease(int arg) {
return state.compareAndSet(1, 0);
}
}
================================================
FILE: 07-09-现实定制Lock类/src/com/concurrency/task/MyLock.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* Զʵ
*/
public class MyLock implements Lock {
/**
* ʵͬ
*/
private AbstractQueuedSynchronizer sync;
/**
* 캯ʼ
*/
public MyLock() {
sync = new MyAbstractQueuedSynchronizer();
}
/**
* ȡ
*/
@Override
public void lock() {
sync.acquire(1);
}
/**
* ȡȡ̻߳ͷţ߳̿Աж
*/
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
/**
* ȡȡͷtrueȡͷfalse
*/
@Override
public boolean tryLock() {
try {
return sync.tryAcquireNanos(1, 1000);
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
/**
* ָʱȡȡͷtrueͷfalse
*
* @param time ʱ
* @param unit ʱ䵥λ
* @return ȡͷtrueͷfalse
* @throws InterruptedException
*/
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, TimeUnit.NANOSECONDS.convert(time, unit));
}
/**
* ͷ
*/
@Override
public void unlock() {
sync.release(1);
}
/**
* һµ
*/
@Override
public Condition newCondition() {
return sync.new ConditionObject();
}
}
================================================
FILE: 07-09-现实定制Lock类/src/com/concurrency/task/Task.java
================================================
package com.concurrency.task;
import java.util.concurrent.TimeUnit;
/**
* Զ
*/
public class Task implements Runnable {
// ʹԶ
private MyLock lock;
//
private String name;
/**
* 캯
*
* @param name
* @param lock ʹõ
*/
public Task(String name, MyLock lock) {
this.lock = lock;
this.name = name;
}
/**
* ֣ʵߣ
*/
@Override
public void run() {
lock.lock();
System.out.printf("Task: %s: Take the lock\n", name);
try {
TimeUnit.SECONDS.sleep(2);
System.out.printf("Task: %s: Free the lock\n", name);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
================================================
FILE: 07-10-实现基于优先级的传输队列/07-10-实现基于优先级的传输队列.iml
================================================
================================================
FILE: 07-10-实现基于优先级的传输队列/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.Consumer;
import com.concurrency.task.Event;
import com.concurrency.task.MyPriorityTransferQueue;
import com.concurrency.task.Producer;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
MyPriorityTransferQueue buffer = new MyPriorityTransferQueue<>();
Producer producer = new Producer(buffer);
Thread producerThreads[] = new Thread[10];
for (int i = 0; i < producerThreads.length; i++) {
producerThreads[i] = new Thread(producer);
producerThreads[i].start();
}
Consumer consumer = new Consumer(buffer);
Thread consumerThread = new Thread(consumer);
consumerThread.start();
System.out.printf("Main: Buffer: Consumer count: %d\n", buffer.getWaitingConsumerCount());
Event myEvent = new Event("Core Event", 0);
buffer.transfer(myEvent);
System.out.printf("Main: My Event has ben transfered.\n");
for (int i = 0; i < producerThreads.length; i++) {
producerThreads[i].join();
}
TimeUnit.SECONDS.sleep(1);
System.out.printf("Main: Buffer: Consumer count: %d\n", buffer.getWaitingConsumerCount());
myEvent = new Event("Core Event 2", 0);
buffer.transfer(myEvent);
consumerThread.join();
System.out.printf("Main: End of the program\n");
}
}
================================================
FILE: 07-10-实现基于优先级的传输队列/src/com/concurrency/task/Consumer.java
================================================
package com.concurrency.task;
/**
*
*/
public class Consumer implements Runnable {
private MyPriorityTransferQueue buffer;
public Consumer(MyPriorityTransferQueue buffer) {
this.buffer = buffer;
}
/**
* 1002Event(в¼), ڿ̨¼̵߳Լ¼ȼpriority
*/
@Override
public void run() {
for (int i = 0; i < 1002; i++) {
try {
Event value = buffer.take();
System.out.printf("Consumer: %s: %d\n", value.getThread(), value.getPriority());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
================================================
FILE: 07-10-实现基于优先级的传输队列/src/com/concurrency/task/Event.java
================================================
package com.concurrency.task;
/**
* Զ¼
*/
public class Event implements Comparable {
// ¼߳
private String thread;
// ߳ȼ
private int priority;
/**
* 캯
*
* @param thread ¼߳
* @param priority ߳ȼ
*/
public Event(String thread, int priority) {
this.thread = thread;
this.priority = priority;
}
public String getThread() {
return thread;
}
public int getPriority() {
return priority;
}
@Override
public int compareTo(Event e) {
if (this.priority > e.getPriority()) {
return -1;
} else if (this.priority < e.getPriority()) {
return 1;
} else {
return 0;
}
}
}
================================================
FILE: 07-10-实现基于优先级的传输队列/src/com/concurrency/task/MyPriorityTransferQueue.java
================================================
package com.concurrency.task;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TransferQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
/**
* Զ߳ȼ
*
* @param Ͳ
*/
public class MyPriorityTransferQueue extends PriorityBlockingQueue implements TransferQueue {
private static final long serialVersionUID = 1L;
// ȴĿ
private AtomicInteger counter;
// 洢ԪصĶ
private LinkedBlockingQueue transfered;
//
private ReentrantLock lock;
/**
* 캯
*/
public MyPriorityTransferQueue() {
counter = new AtomicInteger(0);
lock = new ReentrantLock();
transfered = new LinkedBlockingQueue<>();
}
/**
* Ԫط͵һڵȴߣûеȴеߣͷfalse
*/
@Override
public boolean tryTransfer(E e) {
lock.lock();
boolean value;
if (counter.get() == 0) {
value = false;
} else {
put(e);
value = true;
}
lock.unlock();
return value;
}
/**
* Ԫط͵һڵȴߣûеȴеߣԪش洢transferУ
* ҵȴͼȡԪصĵһߣǰ̱߳
*/
@Override
public void transfer(E e) throws InterruptedException {
lock.lock();
if (counter.get() != 0) {
put(e);
lock.unlock();
} else {
transfered.add(e);
lock.unlock();
synchronized (e) {
e.wait();
}
}
}
/**
* һԱʾѵԪ, ڶʾûȴһߵʱ䣬
* ʾȴʱĵ λڵȴԪءָ
* ʱתΪ벢ʹ wait()߳ߡȡԪʱ߳wait()
* ߣʹnotify()ȥ
*/
@Override
public boolean tryTransfer(E e, long timeout, TimeUnit unit)
throws InterruptedException {
lock.lock();
if (counter.get() != 0) {
put(e);
lock.unlock();
return true;
} else {
transfered.add(e);
long newTimeout = TimeUnit.MILLISECONDS.convert(timeout, unit);
lock.unlock();
e.wait(newTimeout);
lock.lock();
if (transfered.contains(e)) {
transfered.remove(e);
lock.unlock();
return false;
} else {
lock.unlock();
return true;
}
}
}
/**
* ʹcounterԵֵ÷ķֵΪ0truefalse
*/
@Override
public boolean hasWaitingConsumer() {
return (counter.get() != 0);
}
/**
* counter Եֵ
*/
@Override
public int getWaitingConsumerCount() {
return counter.get();
}
/**
* transferedûԪأͷʹtoke()Ӷȡ
* һԪزٴλȡ.ûԪأ÷ֱ߳Ԫؿɱ
*/
@Override
public E take() throws InterruptedException {
lock.lock();
counter.incrementAndGet();
E value = transfered.poll();
if (value == null) {
lock.unlock();
value = super.take();
lock.lock();
} else {
synchronized (value) {
value.notify();
}
}
counter.decrementAndGet();
lock.unlock();
return value;
}
}
================================================
FILE: 07-10-实现基于优先级的传输队列/src/com/concurrency/task/Producer.java
================================================
package com.concurrency.task;
/**
*
*/
public class Producer implements Runnable {
// // 洢ɵ¼
private MyPriorityTransferQueue buffer;
public Producer(MyPriorityTransferQueue buffer) {
this.buffer = buffer;
}
/**
* 100EventʹôΪȼ¼ ԽȼԽ)
* ʹput()Dz뵽С
*/
@Override
public void run() {
for (int i = 0; i < 100; i++) {
Event event = new Event(Thread.currentThread().getName(), i);
buffer.put(event);
}
}
}
================================================
FILE: 07-11-实现自己的原子对象/07-11-实现自己的原子对象.iml
================================================
================================================
FILE: 07-11-实现自己的原子对象/src/com/concurrency/core/Main.java
================================================
package com.concurrency.core;
import com.concurrency.task.ParkingCounter;
import com.concurrency.task.Sensor1;
import com.concurrency.task.Sensor2;
public class Main {
public static void main(String[] args) throws Exception {
// ͣ
ParkingCounter counter = new ParkingCounter(5);
//
Sensor1 sensor1 = new Sensor1(counter);
Sensor2 sensor2 = new Sensor2(counter);
Thread thread1 = new Thread(sensor1);
Thread thread2 = new Thread(sensor2);
thread1.start();
thread2.start();
// ȴн
thread1.join();
thread2.join();
// ͣеijĿ
System.out.printf("Main: Number of cars: %d\n", counter.get());
// Ϣн
System.out.printf("Main: End of the program.\n");
}
}
================================================
FILE: 07-11-实现自己的原子对象/src/com/concurrency/task/ParkingCounter.java
================================================
package com.concurrency.task;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Զԭ࣬ͣ
*/
public class ParkingCounter extends AtomicInteger {
private static final long serialVersionUID = 1L;
// ͣĿ
private int maxNumber;
/**
* 캯
* @param maxNumber ͣĿ
*/
public ParkingCounter(int maxNumber) {
set(0);
this.maxNumber = maxNumber;
}
/**
* ͣ
*
* @return ͣɹtruefalse
*/
public boolean carIn() {
for (; ; ) {
int value = get();
if (value == maxNumber) {
System.out.printf("ParkingCounter: The parking is full.\n");
return false;
} else {
int newValue = value + 1;
boolean changed = compareAndSet(value, newValue);
if (changed) {
System.out.printf("ParkingCounter: A car has entered.\n");
return true;
}
}
}
}
/**
* 뿪
* @return ɹtruefalse
*/
public boolean carOut() {
for (; ; ) {
int value = get();
if (value == 0) {
System.out.printf("ParkingCounter: The parking is empty.\n");
return false;
} else {
int newValue = value - 1;
boolean changed = compareAndSet(value, newValue);
if (changed) {
System.out.printf("ParkingCounter: A car has gone out.\n");
return true;
}
}
}
}
}
================================================
FILE: 07-11-实现自己的原子对象/src/com/concurrency/task/Sensor1.java
================================================
package com.concurrency.task;
/**
* ࣬ģͣ
*/
public class Sensor1 implements Runnable {
// ͣ
private ParkingCounter counter;
/**
* 캯
*
* @param counter ͣ
*/
public Sensor1(ParkingCounter counter) {
this.counter = counter;
}
/**
* ͣģ
*/
@Override
public void run() {
counter.carIn();
counter.carIn();
counter.carIn();
counter.carIn();
counter.carOut();
counter.carOut();
counter.carOut();
counter.carIn();
counter.carIn();
counter.carIn();
}
}
================================================
FILE: 07-11-实现自己的原子对象/src/com/concurrency/task/Sensor2.java
================================================
package com.concurrency.task;
/**
* ࣬ģͣ
*/
public class Sensor2 implements Runnable {
// ͣ
private ParkingCounter counter;
/**
* 캯
*
* @param counter ͣ
*/
public Sensor2(ParkingCounter counter) {
this.counter=counter;
}
/**
* ͣģ
*/
@Override
public void run() {
counter.carIn();
counter.carOut();
counter.carOut();
counter.carIn();
counter.carIn();
counter.carIn();
counter.carIn();
counter.carIn();
counter.carIn();
}
}
================================================
FILE: README.md
================================================
# java 7 并发编程实战手册
================================================
FILE: Template/Template.iml
================================================