├── .idea ├── .name ├── codeStyleSettings.xml ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── findbugs-idea.xml ├── misc.xml ├── modules.xml ├── scopes │ └── scope_settings.xml ├── uiDesigner.xml └── vcs.xml ├── 01-02-线程的创建和运行 ├── 01-02-线程的创建和运行.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── Calculator.java ├── 01-03-线程信息的获取和设置 ├── 01-03-线程信息的获取和设置.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── Calculator.java ├── 01-04-线程的中断 ├── 01-04-线程的中断.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── PrimeGenerator.java ├── 01-05-线程中断的控制 ├── 01-05-线程中断的控制.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── FileSearch.java ├── 01-06-线程的休眠和恢复 ├── 01-06-线程的休眠和恢复.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── FileClock.java ├── 01-07-等待线程的终止 ├── 01-07-等待线程的终止.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── DataSourcesLoader.java │ └── NetworkConnectionsLoader.java ├── 01-08-守护线程的创建和运行 ├── 01-08-守护线程的创建和运行.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── event │ └── Event.java │ └── task │ ├── CleanerTask.java │ └── WriterTask.java ├── 01-09-线程中不可控异常的处理 ├── 01-09-线程中不可控异常的处理.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── handler │ └── ExceptionHandler.java │ └── task │ └── Task.java ├── 01-10-线程局部变量的使用 ├── 01-10-线程局部变量的使用.iml └── src │ └── com │ └── concurrency │ ├── core │ ├── Main.java │ └── SafeMain.java │ └── task │ ├── SafeTask.java │ └── UnsafeTask.java ├── 01-11-线程分组 ├── 01-11-线程分组.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Result.java │ └── SearchTask.java ├── 01-12-线程组中不可控制异常的处理 ├── 01-12-线程组中不可控制异常的处理.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── group │ └── MyThreadGroup.java │ └── task │ └── Task.java ├── 01-13-使用工厂类创建线程 ├── 01-13-使用工厂类创建线程.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── factory │ └── MyThreadFactory.java │ └── task │ └── Task.java ├── 02-02-使用synchronized实现同步方法-问题 ├── 02-02-使用synchronized实现同步方法-问题.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Account.java │ ├── Bank.java │ └── Company.java ├── 02-02-使用synchronized实现同步方法-问题解决 ├── 02-02-使用synchronized实现同步方法-问题解决.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Account.java │ ├── Bank.java │ └── Company.java ├── 02-03-使用非依赖属性实现同步 ├── 02-03-使用非依赖属性实现同步.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Cinema.java │ ├── TicketOffice1.java │ └── TicketOffice2.java ├── 02-04-在同步代码中使用条件 ├── 02-04-在同步代码中使用条件.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Consumer.java │ ├── EventStorage.java │ └── Producer.java ├── 02-05-用锁实现同步 ├── 02-05-用锁实现同步.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Job.java │ └── PrintQueue.java ├── 02-06-使用读写锁实现同步数据访问 ├── 02-06-使用读写锁实现同步数据访问.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── PricesInfo.java │ ├── Reader.java │ └── Writer.java ├── 02-07-修改锁的公平性 ├── 02-07-修改锁的公平性.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Job.java │ └── PrintQueue.java ├── 02-08-在锁中使用多条件 ├── 02-08-在锁中使用多条件.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── task │ ├── Consumer.java │ └── Producer.java │ └── utils │ ├── Buffer.java │ └── FileMock.java ├── 02-09-应用例子 ├── 02-09-应用例子.iml └── src │ └── com.concurrency │ ├── core │ └── Main.java │ └── task │ ├── BuildStats.java │ ├── Sensor1.java │ └── Sensor2.java ├── 03-02-资源并发控制访问 ├── 03-02-资源并发控制访问.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Job.java │ └── PrintQueue.java ├── 03-03-资源的多副本的并发访问控制 ├── 03-03-资源的多副本的并发访问控制.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Job.java │ └── PrintQueue.java ├── 03-04-等待多个并发事件的完成 ├── 03-04-等待多个并发事件的完成.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Participant.java │ └── VideoConference.java ├── 03-05-在集合点的同步 ├── 03-05-在集合点的同步.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── task │ ├── Grouper.java │ └── Searcher.java │ └── utils │ ├── MatrixMock.java │ └── Results.java ├── 03-06-并发阶段任务的运行 ├── 03-06-并发阶段任务的运行.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── FileSearch.java ├── 03-07-并发阶段任务中的阶段切换 ├── 03-07-并发阶段任务中的阶段切换.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── MyPhaser.java │ └── Student.java ├── 03-08-并发任务间的数据交换 ├── 03-08-并发任务间的数据交换.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Consumer.java │ └── Producer.java ├── 04-02-创建线程执行器 ├── 04-02-创建线程执行器.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Server.java │ └── Task.java ├── 04-03-创建固定大小的线程执行器 ├── 04-03-创建固定大小的线程执行器.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Server.java │ └── Task.java ├── 04-04-在执行器中执行任务并返回结果 ├── 04-04-在执行器中执行任务并返回结果.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── FactorialCalculator.java ├── 04-05-运行多个任务并处理第一个结果 ├── 04-05-运行多个任务并处理第一个结果.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── TaskValidator.java │ └── UserValidator.java ├── 04-06-运行多个任务并且处理所有结果 ├── 04-06-运行多个任务并且处理所有结果.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Result.java │ └── Task.java ├── 04-07-在执行器中延时执行任务 ├── 04-07-在执行器中延时执行任务.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── Task.java ├── 04-08-在执行器中周期性执行任务 ├── 04-08-在执行器中周期性执行任务.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── Task.java ├── 04-09-在执行器中取消任务 ├── 04-09-在执行器中取消任务.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── Task.java ├── 04-10-在执行器中控制任务的完成 ├── 04-10-在执行器中控制任务的完成.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── ExecutableTask.java │ └── ResultTask.java ├── 04-11-在执行器中分离任务的启动与结果的处理 ├── 04-11-在执行器中分离任务的启动与结果的处理.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── ReportGenerator.java │ ├── ReportProcessor.java │ └── ReportRequest.java ├── 04-12-处理在执行器中被拒绝的任务 ├── 04-12-处理在执行器中被拒绝的任务.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── RejectedTaskController.java │ └── Task.java ├── 05-02-创建Fork-Join线程池 ├── 05-02-创建Fork-Join线程池.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── task │ └── Task.java │ └── utils │ ├── Product.java │ └── ProductListGenerator.java ├── 05-03-合并任务的结果 ├── 05-03-合并任务的结果.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── task │ ├── DocumentTask.java │ └── LineTask.java │ └── utils │ └── DocumentMock.java ├── 05-04-异步运行任务 ├── 05-04-异步运行任务.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── FolderProcessor.java ├── 05-05-在任务中抛出异常 ├── 05-05-在任务中抛出异常.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── Task.java ├── 05-06-取消任务 ├── 05-06-取消任务.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── task │ └── TaskManager.java │ └── utils │ ├── ArrayGenerator.java │ └── SearchNumberTask.java ├── 06-02-使用非阻塞式线程安全列表 ├── 06-02-使用非阻塞式线程安全列表.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── AddTask.java │ └── PollTask.java ├── 06-03-使用阻塞式线程安全列表 ├── 06-03-使用阻塞式线程安全列表.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── Client.java ├── 06-04-使用按优先级排序的阻塞式线程安全列表 ├── 06-04-使用按优先级排序的阻塞式线程安全列表.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Event.java │ └── Task.java ├── 06-05-使用带有延迟元素的线程安全列表 ├── 06-05-使用带有延迟元素的线程安全列表.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Event.java │ └── Task.java ├── 06-06-使用线程安全可遍历映射 ├── 06-06-使用线程安全可遍历映射.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── task │ └── Task.java │ └── utils │ └── Contact.java ├── 06-07-生成并发随机数 ├── 06-07-生成并发随机数.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── TaskLocalRandom.java ├── 06-08-使用原子变量 ├── 06-08-使用原子变量.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Account.java │ ├── Bank.java │ └── Company.java ├── 06-09-使用原子数组 ├── 06-09-使用原子数组.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Decrementer.java │ └── Incrementer.java ├── 07-02-定制ThreadPoolExecutor类 ├── 07-02-定制ThreadPoolExecutor类.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ ├── executor │ └── MyExecutor.java │ └── task │ └── SleepTwoSecondsTask.java ├── 07-03-基于优先级的Executor类 ├── 07-03-基于优先级的Executor类.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ └── MyPriorityTask.java ├── 07-04-实现ThreadFactory接口生成定制线程 ├── 07-04-实现ThreadFactory接口生成定制线程.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── MyTask.java │ ├── MyThread.java │ └── MyThreadFactory.java ├── 07-05-在Executro对象中使用ThreadFactory ├── 07-05-在Executro对象中使用ThreadFactory.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── MyTask.java │ ├── MyThread.java │ └── MyThreadFactory.java ├── 07-06-定制运行在线程池中的任务 ├── 07-06-定制运行在线程池中的任务.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── MyScheduledTask.java │ ├── MyScheduledThreadPoolExecutor.java │ └── Task.java ├── 07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程 ├── 07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── MyRecursiveTask.java │ ├── MyWorkerThread.java │ └── MyWorkerThreadFactory.java ├── 07-08-定制运行在Fork-Join框架中的任务 ├── 07-08-定制运行在Fork-Join框架中的任务.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── MyWorkerTask.java │ └── Task.java ├── 07-09-现实定制Lock类 ├── 07-09-现实定制Lock类.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── MyAbstractQueuedSynchronizer.java │ ├── MyLock.java │ └── Task.java ├── 07-10-实现基于优先级的传输队列 ├── 07-10-实现基于优先级的传输队列.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── Consumer.java │ ├── Event.java │ ├── MyPriorityTransferQueue.java │ └── Producer.java ├── 07-11-实现自己的原子对象 ├── 07-11-实现自己的原子对象.iml └── src │ └── com │ └── concurrency │ ├── core │ └── Main.java │ └── task │ ├── ParkingCounter.java │ ├── Sensor1.java │ └── Sensor2.java ├── README.md └── Template └── Template.iml /.idea/.name: -------------------------------------------------------------------------------- 1 | JAVA7并发编程实战手册 -------------------------------------------------------------------------------- /.idea/codeStyleSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 13 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /01-02-线程的创建和运行/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Calculator; 4 | 5 | public class Main { 6 | public static void main(String[] args) { 7 | // 创建一个执行10次的循环。在每次循环中创建一个Calculator 对象, 8 | // 一个Thread对象,这个Thread对象使用刚创建的Calculator对象作为构造器的参数, 9 | // 然后调用刚创建的Thread对象的start()方法。 10 | for (int i = 0; i <= 10; i++) { 11 | Calculator calculator = new Calculator(i); 12 | Thread thread = new Thread(calculator); 13 | thread.start(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /01-02-线程的创建和运行/src/com/concurrency/task/Calculator.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | // 创建一个名为Calculator的类,它实现了 Runnable接口 4 | public class Calculator implements Runnable { 5 | // 声明一个名为number的私有(private) int属性 6 | private int number; 7 | 8 | // 编写这个类的一个构造器,用来为属性number设置值。 9 | public Calculator(int number) { 10 | this.number = number; 11 | } 12 | 13 | // run方法。这个方法用来执行我们创建的线程的指令,它将对指定的数字进行乘法表运算。 14 | @Override 15 | public void run() { 16 | for (int i = 1; i <= 10; i++) { 17 | System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(), number, i, number * i); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /01-03-线程信息的获取和设置/src/com/concurrency/task/Calculator.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | public class Calculator implements Runnable{ 4 | private int number; 5 | 6 | public Calculator(int number) { 7 | this.number = number; 8 | } 9 | 10 | @Override 11 | public void run() { 12 | // 指定的数字进行乘法表运算。 13 | for (int i = 1; i <= 10; i++) { 14 | System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(), number, i, number * i); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /01-04-线程的中断/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.PrimeGenerator; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | 10 | Thread task = new PrimeGenerator(); 11 | task.start(); // 启动质数生成线程 12 | try { 13 | TimeUnit.SECONDS.sleep(5); // 主线程休眠5s 14 | } catch (InterruptedException e) { 15 | e.printStackTrace(); 16 | } 17 | 18 | task.interrupt(); // 质数生成线程中断 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /01-04-线程的中断/src/com/concurrency/task/PrimeGenerator.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | public class PrimeGenerator extends Thread { 4 | @Override 5 | public void run() { 6 | long number = 1L; 7 | 8 | while (true) { 9 | // 对每个数字,计算它是不是一个质数,如果是的话就打印到控制台。 10 | if (isPrime(number)) { 11 | System.out.printf("Number %d is Prime\n", number); 12 | } 13 | 14 | // 当被中断时,输出一条消息,并且退出方法 15 | if (isInterrupted()) { 16 | System.out.printf("The Prime Generator has been Interrupted\n"); 17 | return; 18 | } 19 | number++; 20 | } 21 | } 22 | 23 | /** 24 | * 判断一个数是否是质数 25 | * 26 | * @param number 待判断的数 27 | * @return true是质数,false不是质数 28 | */ 29 | private boolean isPrime(long number) { 30 | if (number <= 2) { 31 | return true; 32 | } 33 | 34 | for (long i = 2; i < number; i++) { 35 | if (number % i == 0) { 36 | return false; 37 | } 38 | } 39 | return true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /01-05-线程中断的控制/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.FileSearch; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建一个运行对象和一个运行它的线程 10 | FileSearch searcher = new FileSearch("C:/", "readme.txt"); 11 | Thread thread = new Thread(searcher); 12 | 13 | thread.start(); // 启动线程 14 | 15 | try { 16 | TimeUnit.SECONDS.sleep(10); // 主线程休眠10s 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | 21 | thread.interrupt(); // 中断线程 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /01-05-线程中断的控制/src/com/concurrency/task/FileSearch.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.io.File; 4 | 5 | // 文件搜索类,给定一个文件目录,搜索其中指定的文件 6 | public class FileSearch implements Runnable { 7 | /** 8 | * 搜索的初始路径 9 | */ 10 | private String initPath; 11 | /** 12 | * 要搜索的文件名 13 | */ 14 | private String fileName; 15 | 16 | 17 | /** 18 | * 构造函数 19 | * 20 | * @param initPath 搜索的初始路径 21 | * @param fileName 要搜索的文件名 22 | */ 23 | public FileSearch(String initPath, String fileName) { 24 | this.initPath = initPath; 25 | this.fileName = fileName; 26 | } 27 | 28 | @Override 29 | public void run() { 30 | 31 | } 32 | 33 | /** 34 | * 清空资源,在本例中为空 35 | */ 36 | private void cleanResources() { 37 | // 不需要做什么 38 | } 39 | 40 | /** 41 | * 处理目录 42 | * 43 | * @param file 待处理的目录 44 | * @throws InterruptedException 线程被中断时抛出异常 45 | */ 46 | private void directoryProcess(File file) throws InterruptedException { 47 | File[] list = file.listFiles(); // 获取当目录中的所有文件 48 | if (list != null) { // 如果当前目录下有文件 49 | for (int i = 0; i < list.length; i++) { // 遍布所有文件 50 | if (list[i].isDirectory()) { // 如果是一个目录 51 | directoryProcess(list[i]); // 递归处理 52 | } else { 53 | fileProcess(list[i]); // 如果是一个文件,调用文件处理方法 54 | } 55 | } 56 | } 57 | } 58 | 59 | /** 60 | * 文件处理方法 61 | * 62 | * @param file 待处理的文件名 63 | * @throws InterruptedException 线程被中断时抛出异常 64 | */ 65 | private void fileProcess(File file) throws InterruptedException { 66 | if (file.getName().equals(this.fileName)) { // 当前文件名与要查找的文件同名,就输出信息 67 | System.out.printf("%s : %s\n", Thread.currentThread().getName(), file.getAbsolutePath()); 68 | } 69 | 70 | if (Thread.interrupted()) { // 程序被中断就抛出异常 71 | throw new InterruptedException(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /01-06-线程的休眠和恢复/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.FileClock; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | public class Main { 7 | public static void main(String[] args) { 8 | // 创建一个文件时间运行对象,并且将其放入一个线程对象中 9 | FileClock clock = new FileClock(); 10 | Thread thread = new Thread(clock); 11 | 12 | // 开始线程 13 | thread.start(); 14 | try { 15 | // 等待五秒 16 | TimeUnit.SECONDS.sleep(5); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | 21 | // 中断线程 22 | thread.interrupt(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /01-06-线程的休眠和恢复/src/com/concurrency/task/FileClock.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | // 文件定时类,每隔一秒钟将实际的时间输出 7 | public class FileClock implements Runnable { 8 | @Override 9 | public void run() { 10 | for (int i = 0; i < 10; i++) { 11 | System.out.printf("%s\n", new Date()); 12 | try { 13 | // 休眠一秒 14 | TimeUnit.SECONDS.sleep(1); 15 | } catch (InterruptedException e) { 16 | // 当线程被中断时,释放或者关闭线程正在使用的资源。 17 | System.out.printf("The FileClock has been interrupted"); 18 | return; // 发生异常就跳出 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /01-07-等待线程的终止/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.DataSourcesLoader; 4 | import com.concurrency.task.NetworkConnectionsLoader; 5 | 6 | import java.util.Date; 7 | 8 | public class Main { 9 | public static void main(String[] args) { 10 | // 创建并启动数据源加载器 11 | DataSourcesLoader dsLoader = new DataSourcesLoader(); 12 | Thread thread1 = new Thread(dsLoader, "DataSourceThread"); 13 | thread1.start(); 14 | 15 | // 创建并且启动网络连接加载器 16 | NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader(); 17 | Thread thread2 = new Thread(ncLoader, "NetworkConnectionLoader"); 18 | thread2.start(); 19 | 20 | // 待待两个线程的任务完成 21 | try { 22 | thread1.join(); 23 | thread2.join(); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | 28 | // 两个任务都完成后输出一条消息 29 | System.out.printf("Main: Configuration has been loaded: %s\n", new Date()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /01-07-等待线程的终止/src/com/concurrency/task/DataSourcesLoader.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 数据源加载器,模拟数据加载,它会休眠10s 8 | */ 9 | public class DataSourcesLoader implements Runnable { 10 | @Override 11 | public void run() { 12 | // 输出一条消息 13 | System.out.printf("Beginning data sources loading: %s\n",new Date()); 14 | 15 | // 休眠10s 16 | try { 17 | TimeUnit.SECONDS.sleep(4); 18 | } catch (InterruptedException e) { 19 | e.printStackTrace(); 20 | } 21 | // 输出一条消息 22 | System.out.printf("Data sources loading has finished: %s\n",new Date()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /01-07-等待线程的终止/src/com/concurrency/task/NetworkConnectionsLoader.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 网络连接加载器,模拟网络连接,它会休眠6s 8 | */ 9 | public class NetworkConnectionsLoader implements Runnable { 10 | @Override 11 | public void run() { 12 | // 输出一条消息 13 | System.out.printf("Begining network connections loading: %s\n",new Date()); 14 | 15 | // 休眠6s 16 | try { 17 | TimeUnit.SECONDS.sleep(6); 18 | } catch (InterruptedException e) { 19 | e.printStackTrace(); 20 | } 21 | // 输出一条消息 22 | System.out.printf("Network connections loading has finished: %s\n",new Date()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /01-08-守护线程的创建和运行/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.event.Event; 4 | import com.concurrency.task.CleanerTask; 5 | import com.concurrency.task.WriterTask; 6 | 7 | import java.util.ArrayDeque; 8 | import java.util.Deque; 9 | 10 | public class Main { 11 | public static void main(String[] args) { 12 | // 创建一个用于存放事件对象的队列 13 | Deque deque = new ArrayDeque(); 14 | 15 | // 创建一个写任务的对象,并且创建三个线程去调用这个对象 16 | WriterTask writer = new WriterTask(deque); 17 | for (int i = 0; i < 3; i++) { 18 | Thread thread = new Thread(writer); 19 | thread.start(); 20 | } 21 | 22 | // 创建一个事件清除任务,并且启动这个任务 23 | CleanerTask cleaner = new CleanerTask(deque); 24 | cleaner.start(); 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /01-08-守护线程的创建和运行/src/com/concurrency/event/Event.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.event; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * 事件类,存储事件信息 7 | */ 8 | public class Event { 9 | /** 10 | * 事件日期 11 | */ 12 | private Date date; 13 | /** 14 | * 事件信息 15 | */ 16 | private String event; 17 | 18 | /** 19 | * 获取事件日期 20 | * 21 | * @return 事件日期 22 | */ 23 | public Date getDate() { 24 | return date; 25 | } 26 | 27 | /** 28 | * 设置事件日期 29 | * 30 | * @param date 事件日期 31 | */ 32 | public void setDate(Date date) { 33 | this.date = date; 34 | } 35 | 36 | /** 37 | * 获取事件信息 38 | * 39 | * @return 事件信息 40 | */ 41 | public String getEvent() { 42 | return event; 43 | } 44 | 45 | /** 46 | * 设置事件信息 47 | * 48 | * @param event 事件信息 49 | */ 50 | public void setEvent(String event) { 51 | this.event = event; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /01-08-守护线程的创建和运行/src/com/concurrency/task/CleanerTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.event.Event; 4 | 5 | import java.util.Date; 6 | import java.util.Deque; 7 | 8 | /** 9 | * 事件清除类,每隔10秒从队尾取出一个事件,并且删除这个事件 10 | */ 11 | public class CleanerTask extends Thread { 12 | 13 | /** 14 | * 用于存储事件对象的队列 15 | */ 16 | Deque deque; 17 | 18 | /** 19 | * 构造函数 20 | * 21 | * @param deque 存储事件对象的队列 22 | */ 23 | public CleanerTask(Deque deque) { 24 | this.deque = deque; 25 | setDaemon(true); // 表明当前对象是一个精灵线程 26 | } 27 | 28 | 29 | @Override 30 | public void run() { 31 | while (true) { 32 | Date date = new Date(); 33 | clean(date); 34 | } 35 | } 36 | 37 | /** 38 | * 清除方法,生存时间长于10秒的事件进行清除 39 | * @param date 当前时间 40 | */ 41 | private void clean(Date date) { 42 | long difference; 43 | boolean delete; 44 | 45 | if (this.deque.size() == 0) { 46 | return; 47 | } 48 | 49 | delete = false; 50 | do { 51 | Event e = this.deque.getLast(); 52 | difference = date.getTime() - e.getDate().getTime(); // 计算最早的事件距离现在的时间 53 | if (difference > 10000) { // 大于10秒就输出信息,并且删除最先发生的事件 54 | System.out.printf("Cleaner: %s\n", e.getEvent()); 55 | deque.removeLast(); 56 | delete = true; 57 | } 58 | } while (difference > 10000); 59 | 60 | if (delete) { // 有删除就输出删除后队列的大小 61 | System.out.printf("Cleaner: Size of the queue: %d\n", deque.size()); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /01-08-守护线程的创建和运行/src/com/concurrency/task/WriterTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.event.Event; 4 | 5 | import java.util.Date; 6 | import java.util.Deque; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * 写事件的类,每一秒钟产生一个事件对象 11 | */ 12 | public class WriterTask implements Runnable { 13 | /** 14 | * 用于存储事件对象的队列 15 | */ 16 | Deque deque; 17 | 18 | /** 19 | * 构造函数 20 | * 21 | * @param deque 存储事件对象的队列 22 | */ 23 | public WriterTask(Deque deque) { 24 | this.deque = deque; 25 | } 26 | 27 | @Override 28 | public void run() { 29 | // 产生100个事件对象 30 | for (int i = 1; i < 100; i++) { 31 | // 创建和初始化事件对象 32 | Event event = new Event(); 33 | event.setDate(new Date()); 34 | event.setEvent(String.format("The thread %s has generated an event", Thread.currentThread().getId())); 35 | 36 | // 将事件添加对队列头部 37 | deque.addFirst(event); 38 | try { 39 | // 休眠一秒种 40 | TimeUnit.SECONDS.sleep(1); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /01-09-线程中不可控异常的处理/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.handler.ExceptionHandler; 4 | import com.concurrency.task.Task; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | Task task = new Task(); // 创建一个任务 9 | Thread thread = new Thread(task); // 创建一个线程 10 | thread.setUncaughtExceptionHandler(new ExceptionHandler()); // 设置线程的异常处理器 11 | thread.start(); 12 | 13 | try { 14 | thread.join(); // 等待线程完成 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | 19 | System.out.printf("Thread has finished\n"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /01-09-线程中不可控异常的处理/src/com/concurrency/handler/ExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.handler; 2 | 3 | /** 4 | * 异常处理类,处理线程中抛出的未捕获的异常 5 | */ 6 | public class ExceptionHandler implements Thread.UncaughtExceptionHandler { 7 | /** 8 | * 处理线程中抛出的未捕获的异常 9 | * @param t 招聘异常的线程 10 | * @param e 抛出的异常 11 | */ 12 | @Override 13 | public void uncaughtException(Thread t, Throwable e) { 14 | System.out.printf("An exception has been captured\n"); 15 | System.out.printf("Thread: %s\n", t.getId()); 16 | System.out.printf("Exception: %s: %s\n", e.getClass().getName(), e.getMessage()); 17 | System.out.printf("Stack Trace: \n"); 18 | e.printStackTrace(System.out); 19 | System.out.printf("Thread status: %s\n", t.getState()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /01-09-线程中不可控异常的处理/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 任务类,专门抛出异常 5 | */ 6 | public class Task implements Runnable { 7 | @Override 8 | public void run() { 9 | // 下面的语句会招聘异常 10 | int number = Integer.parseInt("TTT"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /01-10-线程局部变量的使用/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.UnsafeTask; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建线程不安全的任务 10 | UnsafeTask task = new UnsafeTask(); 11 | 12 | // 将任务入进三个不同的线程中 13 | for (int i = 0; i < 3; i++) { 14 | Thread thread = new Thread(task); 15 | thread.start(); 16 | try { 17 | TimeUnit.SECONDS.sleep(2); 18 | } catch (InterruptedException e) { 19 | e.printStackTrace(); 20 | } 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /01-10-线程局部变量的使用/src/com/concurrency/core/SafeMain.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.SafeTask; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class SafeMain { 8 | public static void main(String[] args) { 9 | // 创建一个任务 10 | SafeTask task = new SafeTask(); 11 | 12 | // 将任务放入三个不同的线程中运行 13 | for (int i = 0; i < 3; i++) { 14 | Thread thread = new Thread(task); 15 | try { 16 | TimeUnit.SECONDS.sleep(2); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | thread.start(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /01-10-线程局部变量的使用/src/com/concurrency/task/SafeTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | public class SafeTask implements Runnable { 7 | /** 8 | * 线程局部变量,其中的内容不能共享,线程被初始化时会创建其包含的变量 9 | */ 10 | private static ThreadLocal startDate = new ThreadLocal() { 11 | @Override 12 | protected Date initialValue() { 13 | return new Date(); 14 | } 15 | }; 16 | 17 | @Override 18 | public void run() { 19 | System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread().getId(), startDate.get()); 20 | try { 21 | TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10)); 22 | } catch (InterruptedException e) { 23 | e.printStackTrace(); 24 | } 25 | 26 | System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread().getId(), startDate.get()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /01-10-线程局部变量的使用/src/com/concurrency/task/UnsafeTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.sql.Time; 4 | import java.util.Date; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * 线程不安全的任务,当这个任务在多个线程中时,其中的变量会被多个线程其享 9 | */ 10 | public class UnsafeTask implements Runnable { 11 | /** 12 | * 日期对象,被所有线程共享 13 | */ 14 | private Date startDate; 15 | 16 | @Override 17 | public void run() { 18 | this.startDate = new Date(); 19 | System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread().getId(), startDate); 20 | try { 21 | TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10)); 22 | } catch (InterruptedException e) { 23 | e.printStackTrace(); 24 | } 25 | 26 | System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread().getId(), startDate); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /01-11-线程分组/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Result; 4 | import com.concurrency.task.SearchTask; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | public class Main { 9 | public static void main(String[] args) { 10 | 11 | // 创建一个线程组 12 | ThreadGroup threadGroup = new ThreadGroup("Searcher"); 13 | // 创建一个结果对象 14 | Result result = new Result(); 15 | 16 | // 创建一个搜索任务,并且创建5个线程去运行这个任务 17 | SearchTask searchTask = new SearchTask(result); 18 | for (int i = 0; i < 5; i++) { 19 | Thread thread = new Thread(threadGroup, searchTask); 20 | thread.start(); 21 | try { 22 | TimeUnit.SECONDS.sleep(1); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | 27 | } 28 | 29 | // 输出线程组的信息 30 | System.out.printf("Number of Threads: %d\n", threadGroup.activeCount()); 31 | System.out.printf("Information about the Thread Group\n"); 32 | threadGroup.list(); // 将有关此线程组的信息打印到标准输出。 33 | 34 | Thread[] threads = new Thread[threadGroup.activeCount()]; // 返回此线程组中活动线程的估计数。 35 | threadGroup.enumerate(threads); // 把此线程组及其子组中的所有活动线程复制到指定数组中。 36 | for (int i = 0; i < threadGroup.activeCount(); i++) { 37 | System.out.printf("Thread %s: %s\n", threads[i].getName(), threads[i].getState()); 38 | } 39 | 40 | // 等待线程结束 41 | waitFinish(threadGroup); 42 | 43 | // 中断线程组中的所有线程 44 | threadGroup.interrupt(); 45 | 46 | } 47 | 48 | /** 49 | * 等待线程组中的一个线程结束 50 | * 51 | * @param threadGroup 线程组 52 | */ 53 | private static void waitFinish(ThreadGroup threadGroup) { 54 | while (threadGroup.activeCount() > 9) { // 如果线程组中的活动线程数大于9个,当前调用线程就休眠1秒,直到线程数小于9个 55 | try { 56 | TimeUnit.SECONDS.sleep(1); 57 | } catch (InterruptedException e) { 58 | e.printStackTrace(); 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /01-11-线程分组/src/com/concurrency/task/Result.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 结果类用于存储搜索结果 5 | */ 6 | public class Result { 7 | /** 8 | * 完成任务的线程名 9 | */ 10 | private String name; 11 | 12 | /** 13 | * 获取完成任务的线程名 14 | * @return 完成任务的线程名 15 | */ 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | /** 21 | * 设置完成任务的线程名 22 | * @param name 完成任务的线程名 23 | */ 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /01-11-线程分组/src/com/concurrency/task/SearchTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.Random; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class SearchTask implements Runnable { 8 | 9 | /** 10 | * 如果线程完成了任务,并且没有中断,就存储线程的名字。 11 | */ 12 | private Result result; 13 | 14 | /** 15 | * 构造函数 16 | * 17 | * @param result 结果对象 18 | */ 19 | public SearchTask(Result result) { 20 | this.result = result; 21 | } 22 | 23 | @Override 24 | public void run() { 25 | String name = Thread.currentThread().getName(); 26 | System.out.printf("Thread %s: Start\n", name); 27 | try { 28 | doTask(); 29 | result.setName(name); 30 | } catch (InterruptedException e) { 31 | System.out.printf("Thread %s: Interrupted\n", name); 32 | return; 33 | } 34 | System.out.printf("Thread %s: End\n", name); 35 | } 36 | 37 | /** 38 | * 模拟搜索操作 39 | * 40 | * @throws InterruptedException 中断异常 41 | */ 42 | private void doTask() throws InterruptedException { 43 | Random random = new Random((new Date()).getTime()); 44 | int value = (int) (random.nextDouble() * 100); 45 | System.out.printf("Thread %s: %d\n", Thread.currentThread().getName(), value); 46 | TimeUnit.SECONDS.sleep(value); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /01-12-线程组中不可控制异常的处理/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.group.MyThreadGroup; 4 | import com.concurrency.task.Task; 5 | 6 | public class Main { 7 | 8 | public static void main(String[] args) { 9 | // 创建一个自定义的线程组 10 | MyThreadGroup threadGroup = new MyThreadGroup("MyThreadGroup"); 11 | // 创建一个任务 12 | Task task = new Task(); 13 | // 创建两个线程,将其放入同一个线程组中,并且执行同一个任务 14 | for (int i = 0; i < 2; i++) { 15 | Thread t = new Thread(threadGroup, task); 16 | t.start(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /01-12-线程组中不可控制异常的处理/src/com/concurrency/group/MyThreadGroup.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.group; 2 | 3 | public class MyThreadGroup extends ThreadGroup { 4 | /** 5 | * 构造函数 6 | * 7 | * @param name 线程组名称 8 | */ 9 | public MyThreadGroup(String name) { 10 | super(name); 11 | } 12 | 13 | /** 14 | * 重写未捕获的异常方法 15 | * 16 | * @param t 抛出异常的信息 17 | * @param e 抛出的异常 18 | */ 19 | @Override 20 | public void uncaughtException(Thread t, Throwable e) { 21 | // 打印线程的名称 22 | System.out.printf("The thread %s has thrown an Exception\n", t.getId()); 23 | // 输出异常栈信息 24 | e.printStackTrace(System.out); 25 | // 中断线程组中其余的线程 26 | System.out.printf("Terminating the rest of the Threads\n"); 27 | interrupt(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /01-12-线程组中不可控制异常的处理/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Random; 4 | 5 | public class Task implements Runnable { 6 | @Override 7 | public void run() { 8 | int result; 9 | // 创建一个随机数生成器 10 | Random random = new Random(Thread.currentThread().getId()); 11 | while (true) { 12 | // 生成一个[0, 1000)内有随机整数,并且有1000除以这个数,求得商 13 | result = 1000 / ((int) (random.nextDouble() * 1000)); 14 | System.out.printf("%s : %d\n", Thread.currentThread().getId(), result); 15 | // 检测当前线程是否被中断 16 | if (Thread.currentThread().isInterrupted()) { 17 | System.out.printf("%d : Interrupted\n", Thread.currentThread().getId()); 18 | return; 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /01-13-使用工厂类创建线程/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.factory.MyThreadFactory; 4 | import com.concurrency.task.Task; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | // 创建一个线程工厂 9 | MyThreadFactory factory = new MyThreadFactory("MyThreadFactory"); 10 | // 创建一个任务 11 | Task task = new Task(); 12 | Thread thread; 13 | 14 | // 创建并且启动10个线程对象 15 | System.out.printf("Starting the Threads\n"); 16 | for (int i = 0; i < 10; i++) { 17 | thread = factory.newThread(task); 18 | thread.start(); 19 | } 20 | // 打印线程工厂的统计信息 21 | System.out.printf("Factory stats:\n"); 22 | System.out.printf("%s\n", factory.getStats()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /01-13-使用工厂类创建线程/src/com/concurrency/factory/MyThreadFactory.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.factory; 2 | 3 | import com.sun.javafx.beans.annotations.NonNull; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Date; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | import java.util.concurrent.ThreadFactory; 10 | 11 | 12 | public class MyThreadFactory implements ThreadFactory { 13 | 14 | private int counter; // 线程计数器,计数已经产生了多少个线程 15 | private String name; // 线程的基准名称 16 | private List stats; // 线程统计信息集合 17 | 18 | /** 19 | * 构造函数 20 | * 21 | * @param name 线程对象的基准名称 22 | */ 23 | public MyThreadFactory(String name) { 24 | this.name = name; 25 | this.counter = 0; 26 | this.stats = new ArrayList(); 27 | } 28 | 29 | /** 30 | * 使用Runnable对象创建一个线程 31 | * 32 | * @param r Runnable对象 33 | * @return 线程对象 34 | */ 35 | @Override 36 | public Thread newThread(Runnable r) { 37 | // 创建一个新的线程对象 38 | Thread t = new Thread(r, this.name + "-Thread_" + this.counter); 39 | this.counter++; 40 | // Actualize the statistics of the factory 41 | this.stats.add(String.format("Created thread %d with name %s on %s\n", t.getId(), t.getName(), new Date())); 42 | return t; 43 | } 44 | 45 | /** 46 | * 获取线程工厂的统计信息 47 | * 48 | * @return 线程工厂的统计信息 49 | */ 50 | public String getStats() { 51 | StringBuffer buffer = new StringBuffer(); 52 | Iterator it = stats.iterator(); 53 | 54 | while (it.hasNext()) { 55 | buffer.append(it.next()); 56 | } 57 | 58 | return buffer.toString(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /01-13-使用工厂类创建线程/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class Task implements Runnable { 6 | @Override 7 | public void run() { 8 | try { 9 | TimeUnit.SECONDS.sleep(1); 10 | } catch (InterruptedException e) { 11 | e.printStackTrace(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /02-02-使用synchronized实现同步方法-问题/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Account; 4 | import com.concurrency.task.Bank; 5 | import com.concurrency.task.Company; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建一个帐户对象 10 | Account account = new Account(); 11 | // 帐户初始值为1000 12 | account.setBalance(1000); 13 | 14 | // 创建一个公司对象,并且让公司对象在一个线程中运行 15 | Company company = new Company(account); 16 | Thread companyThread = new Thread(company); 17 | 18 | // 创建一个银行对象,并且让银行对象在一个线程中运行 19 | Bank bank = new Bank(account); 20 | Thread bankThread = new Thread(bank); 21 | 22 | // 输出初始的余额 23 | System.out.printf("Account : Initial Balance: %f\n", account.getBalance()); 24 | 25 | // 启动公司和银行两个线程 26 | companyThread.start(); 27 | bankThread.start(); 28 | 29 | try { 30 | // 等待两个线程的完成 31 | companyThread.join(); 32 | bankThread.join(); 33 | // 输出最后的余额 34 | System.out.printf("Account : Final Balance: %f\n", account.getBalance()); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /02-02-使用synchronized实现同步方法-问题/src/com/concurrency/task/Account.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 帐户类,模拟一个银行帐户 5 | */ 6 | public class Account { 7 | /** 8 | * 帐户余额 9 | */ 10 | private double balance; 11 | 12 | /** 13 | * 获取帐户余额 14 | * 15 | * @return 帐户余额 16 | */ 17 | public double getBalance() { 18 | return balance; 19 | } 20 | 21 | /** 22 | * 设置帐户余额 23 | * 24 | * @param balance 帐户余额 25 | */ 26 | public void setBalance(double balance) { 27 | this.balance = balance; 28 | } 29 | 30 | /** 31 | * 增加帐户余额 32 | * 33 | * @param amount 增加的余额 34 | */ 35 | public void addAccount(double amount) { 36 | double tmp = balance; 37 | try { 38 | Thread.sleep(10); 39 | } catch (InterruptedException e) { 40 | e.printStackTrace(); 41 | } 42 | 43 | tmp += amount; 44 | balance = tmp; 45 | } 46 | 47 | /** 48 | * 减少帐户余额 49 | * 50 | * @param amount 减少的余额 51 | */ 52 | public void subtractAmount(double amount) { 53 | double tmp = balance; 54 | try { 55 | Thread.sleep(10); 56 | } catch (InterruptedException e) { 57 | e.printStackTrace(); 58 | } 59 | 60 | tmp -= amount; 61 | balance = tmp; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /02-02-使用synchronized实现同步方法-问题/src/com/concurrency/task/Bank.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | public class Bank implements Runnable { 4 | /** 5 | * 一个帐户 6 | */ 7 | private Account account; 8 | 9 | /** 10 | * 构造函数 11 | * 12 | * @param account 银行帐户 13 | */ 14 | public Bank(Account account) { 15 | this.account = account; 16 | } 17 | 18 | 19 | @Override 20 | public void run() { 21 | for (int i = 0; i < 100; i++) { 22 | this.account.subtractAmount(1000); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /02-02-使用synchronized实现同步方法-问题/src/com/concurrency/task/Company.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | public class Company implements Runnable { 4 | 5 | /** 6 | * 一个帐户 7 | */ 8 | private Account account; 9 | 10 | /** 11 | * 构造函数 12 | * @param account 帐户对象 13 | */ 14 | public Company(Account account) { 15 | this.account = account; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | for (int i = 0; i < 100; i++) { 21 | this.account.addAccount(1000); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Account; 4 | import com.concurrency.task.Bank; 5 | import com.concurrency.task.Company; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建一个帐户对象 10 | Account account = new Account(); 11 | // 帐户初始值为1000 12 | account.setBalance(1000); 13 | 14 | // 创建一个公司对象,并且让公司对象在一个线程中运行 15 | Company company = new Company(account); 16 | Thread companyThread = new Thread(company); 17 | 18 | // 创建一个银行对象,并且让银行对象在一个线程中运行 19 | Bank bank = new Bank(account); 20 | Thread bankThread = new Thread(bank); 21 | 22 | // 输出初始的余额 23 | System.out.printf("Account : Initial Balance: %f\n", account.getBalance()); 24 | 25 | // 启动公司和银行两个线程 26 | companyThread.start(); 27 | bankThread.start(); 28 | 29 | try { 30 | // 等待两个线程的完成 31 | companyThread.join(); 32 | bankThread.join(); 33 | // 输出最后的余额 34 | System.out.printf("Account : Final Balance: %f\n", account.getBalance()); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/task/Account.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 帐户类,模拟一个银行帐户 5 | */ 6 | public class Account { 7 | /** 8 | * 帐户余额 9 | */ 10 | private double balance; 11 | 12 | /** 13 | * 获取帐户余额 14 | * 15 | * @return 帐户余额 16 | */ 17 | public double getBalance() { 18 | return balance; 19 | } 20 | 21 | /** 22 | * 设置帐户余额 23 | * 24 | * @param balance 帐户余额 25 | */ 26 | public void setBalance(double balance) { 27 | this.balance = balance; 28 | } 29 | 30 | /** 31 | * 增加帐户余额 32 | * 33 | * @param amount 增加的余额 34 | */ 35 | public synchronized void addAccount(double amount) { 36 | double tmp = balance; 37 | try { 38 | Thread.sleep(10); 39 | } catch (InterruptedException e) { 40 | e.printStackTrace(); 41 | } 42 | 43 | tmp += amount; 44 | balance = tmp; 45 | } 46 | 47 | /** 48 | * 减少帐户余额 49 | * 50 | * @param amount 减少的余额 51 | */ 52 | public synchronized void subtractAmount(double amount) { 53 | double tmp = balance; 54 | try { 55 | Thread.sleep(10); 56 | } catch (InterruptedException e) { 57 | e.printStackTrace(); 58 | } 59 | 60 | tmp -= amount; 61 | balance = tmp; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/task/Bank.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | public class Bank implements Runnable { 4 | /** 5 | * 一个帐户 6 | */ 7 | private Account account; 8 | 9 | /** 10 | * 构造函数 11 | * 12 | * @param account 银行帐户 13 | */ 14 | public Bank(Account account) { 15 | this.account = account; 16 | } 17 | 18 | 19 | @Override 20 | public void run() { 21 | for (int i = 0; i < 100; i++) { 22 | this.account.subtractAmount(1000); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /02-02-使用synchronized实现同步方法-问题解决/src/com/concurrency/task/Company.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | public class Company implements Runnable { 4 | 5 | /** 6 | * 一个帐户 7 | */ 8 | private Account account; 9 | 10 | /** 11 | * 构造函数 12 | * @param account 帐户对象 13 | */ 14 | public Company(Account account) { 15 | this.account = account; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | for (int i = 0; i < 100; i++) { 21 | this.account.addAccount(1000); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /02-03-使用非依赖属性实现同步/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Cinema; 4 | import com.concurrency.task.TicketOffice1; 5 | import com.concurrency.task.TicketOffice2; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建一个电影院对象 10 | Cinema cinema = new Cinema(); 11 | 12 | // 创建一个出售一号影院厅票的售票窗口对象,并且让其在一个线程中运行 13 | TicketOffice1 ticketOffice1 = new TicketOffice1(cinema); 14 | Thread thread1 = new Thread(ticketOffice1, "TicketOffice1"); 15 | 16 | // 创建一个出售二号影院厅票的售票窗口对象,并且让其在一个线程中运行 17 | TicketOffice2 ticketOffice2 = new TicketOffice2(cinema); 18 | Thread thread2 = new Thread(ticketOffice2, "TicketOffice2"); 19 | 20 | // 启动两个售票窗口线程 21 | thread1.start(); 22 | thread2.start(); 23 | 24 | try { 25 | // 等待两个线程完成 26 | thread1.join(); 27 | thread2.join(); 28 | } catch (InterruptedException e) { 29 | e.printStackTrace(); 30 | } 31 | 32 | // 输出电影院剩余的票数 33 | System.out.printf("Room 1 Vacancies: %d\n", cinema.getVacanciesCinema1()); 34 | System.out.printf("Room 2 Vacancies: %d\n", cinema.getVacanciesCinema2()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /02-03-使用非依赖属性实现同步/src/com/concurrency/task/Cinema.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 影院类,其有两个影院厅 5 | */ 6 | public class Cinema { 7 | /** 8 | * 保存影院厅1的剩余电影票数 9 | */ 10 | private long vacanciesCinema1; 11 | /** 12 | * 保存影院厅2的剩余电影票数 13 | */ 14 | private long vacanciesCinema2; 15 | /** 16 | * 控制vacanciesCinema1同步访问的对象 17 | */ 18 | private final Object controlCinema1; 19 | /** 20 | * 控制 vacanciesCinema2同步访问的对象 21 | */ 22 | private final Object controlCinema2; 23 | 24 | public Cinema() { 25 | controlCinema1 = new Object(); // 初始化同步控制变量 26 | controlCinema2 = new Object(); // 初始化同步控制变量 27 | vacanciesCinema1 = 20; // 设置初始空闲票数 28 | vacanciesCinema2 = 20; // 设置初始空闲票数 29 | } 30 | 31 | /** 32 | * 出售影院厅1的门票 33 | * 34 | * @param number 出售的门票张数 35 | * @return true出售成功,false出售失败 36 | */ 37 | public boolean sellTickets1(int number) { 38 | synchronized (controlCinema1) { 39 | if (number < vacanciesCinema1) { 40 | vacanciesCinema1 -= number; 41 | return true; 42 | } else { 43 | return false; 44 | } 45 | } 46 | } 47 | 48 | /** 49 | * 出售影院厅2的门票 50 | * 51 | * @param number 出售的门票张数 52 | * @return true出售成功,false出售失败 53 | */ 54 | public boolean sellTickets2(int number) { 55 | synchronized (controlCinema2) { 56 | if (number < vacanciesCinema2) { 57 | vacanciesCinema2 -= number; 58 | return true; 59 | } else { 60 | return false; 61 | } 62 | } 63 | } 64 | 65 | /** 66 | * 向售影院厅1退门票 67 | * 68 | * @param number 退的门票张数 69 | * @return true退票成功,总返回true 70 | */ 71 | public boolean returnTickets1(int number) { 72 | synchronized (controlCinema1) { 73 | vacanciesCinema1 += number; 74 | return true; 75 | } 76 | } 77 | 78 | /** 79 | * 向售影院厅2退门票 80 | * 81 | * @param number 退的门票张数 82 | * @return true退票成功,总返回true 83 | */ 84 | public boolean returnTickets2(int number) { 85 | synchronized (controlCinema2) { 86 | vacanciesCinema2 += number; 87 | return true; 88 | } 89 | } 90 | 91 | /** 92 | * 获取影院厅1剩余的门票数 93 | * 94 | * @return 影院1剩余的门票数 95 | */ 96 | public long getVacanciesCinema1() { 97 | return vacanciesCinema1; 98 | } 99 | 100 | /** 101 | * 获取影院厅2剩余的门票数 102 | * 103 | * @return 影院2剩余的门票数 104 | */ 105 | public long getVacanciesCinema2() { 106 | return vacanciesCinema2; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /02-03-使用非依赖属性实现同步/src/com/concurrency/task/TicketOffice1.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 售票窗口类,出售1号放映厅的票 5 | */ 6 | public class TicketOffice1 implements Runnable { 7 | /** 8 | * 电影院对象 9 | */ 10 | private Cinema cinema; 11 | 12 | /** 13 | * 构造函数 14 | * @param cinema 电影院对象 15 | */ 16 | public TicketOffice1(Cinema cinema) { 17 | this.cinema = cinema; 18 | } 19 | 20 | @Override 21 | public void run() { 22 | cinema.sellTickets1(3); 23 | cinema.sellTickets1(2); 24 | cinema.sellTickets2(2); 25 | cinema.returnTickets1(3); 26 | cinema.sellTickets1(5); 27 | cinema.sellTickets2(2); 28 | cinema.sellTickets2(2); 29 | cinema.sellTickets2(2); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /02-03-使用非依赖属性实现同步/src/com/concurrency/task/TicketOffice2.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 售票窗口类,出售2号放映厅的票 5 | */ 6 | public class TicketOffice2 implements Runnable { 7 | /** 8 | * 电影院对象 9 | */ 10 | private Cinema cinema; 11 | 12 | /** 13 | * 构造函数 14 | * 15 | * @param cinema 电影院对象 16 | */ 17 | public TicketOffice2(Cinema cinema) { 18 | this.cinema = cinema; 19 | } 20 | 21 | @Override 22 | public void run() { 23 | cinema.sellTickets2(2); 24 | cinema.sellTickets2(4); 25 | cinema.sellTickets1(2); 26 | cinema.sellTickets1(1); 27 | cinema.returnTickets2(2); 28 | cinema.sellTickets1(3); 29 | cinema.sellTickets2(2); 30 | cinema.sellTickets1(2); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /02-04-在同步代码中使用条件/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Consumer; 4 | import com.concurrency.task.EventStorage; 5 | import com.concurrency.task.Producer; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建一个事件存储对象 10 | EventStorage storage = new EventStorage(); 11 | 12 | // 创建一个事件生产者对象,并且将其放入到一个线程中运行 13 | Producer producer = new Producer(storage); 14 | Thread thread1 = new Thread(producer); 15 | 16 | // 创建一个事件消费者对象,并且将其放入到一个线程中运行 17 | Consumer consumer = new Consumer(storage); 18 | Thread thread2 = new Thread(consumer); 19 | 20 | // 启动两线程 21 | thread2.start(); 22 | thread1.start(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /02-04-在同步代码中使用条件/src/com/concurrency/task/Consumer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 消费者对象,消费事件 5 | */ 6 | public class Consumer implements Runnable { 7 | /** 8 | * 事件存储对象 9 | */ 10 | private EventStorage storage; 11 | 12 | /** 13 | * 构造函数 14 | * 15 | * @param storage 事件存储对象 16 | */ 17 | public Consumer(EventStorage storage) { 18 | this.storage = storage; 19 | } 20 | 21 | @Override 22 | public void run() { 23 | for (int i = 0; i < 100; i++) { 24 | this.storage.get(); // 消费事件 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /02-04-在同步代码中使用条件/src/com/concurrency/task/EventStorage.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | /** 8 | * 事件存储类,生产者会存储事件,消费者会处理存储的事件,一个事件就是一个日期对象 9 | */ 10 | public class EventStorage { 11 | /** 12 | * 最多可以保存的事件数 13 | */ 14 | private int maxSize; 15 | 16 | /** 17 | * 存储事件的集合 18 | */ 19 | private List storage; 20 | 21 | /** 22 | * 构造函数 23 | */ 24 | public EventStorage() { 25 | this.maxSize = 10; // 最多可以存储10个事件 26 | this.storage = new LinkedList(); // 初始化事件存储集合 27 | } 28 | 29 | /** 30 | * 同步方法,向事件集合中添加一个事件 31 | */ 32 | public synchronized void set() { 33 | while (this.storage.size() == this.maxSize) { // 如果集合已经满了,就等待 34 | try { 35 | wait(); 36 | } catch (InterruptedException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | 41 | this.storage.add(new Date()); // 产生事件 42 | System.out.printf("Set: %d\n", storage.size()); 43 | notify(); // 唤醒其它线程 44 | } 45 | 46 | /** 47 | * 同步方法,使用处理事件集合中的一个事件 48 | */ 49 | public synchronized void get() { 50 | while (this.storage.size() == 0) { // 如果集合为空就等待 51 | try { 52 | wait(); 53 | } catch (InterruptedException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | 58 | System.out.printf("Get: %d: %s\n", storage.size(), ((LinkedList) storage).poll()); // 消费一个事件 59 | notify(); // 唤醒其它线程 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /02-04-在同步代码中使用条件/src/com/concurrency/task/Producer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 生产者对象,生产事件 5 | */ 6 | public class Producer implements Runnable { 7 | /** 8 | * 事件存储对象 9 | */ 10 | private EventStorage storage; 11 | 12 | /** 13 | * 构造函数 14 | * 15 | * @param storage 事件存储对象 16 | */ 17 | public Producer(EventStorage storage) { 18 | this.storage = storage; 19 | } 20 | 21 | @Override 22 | public void run() { 23 | for (int i = 0; i < 100; i++) { 24 | this.storage.set(); // 产生事件 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /02-05-用锁实现同步/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Job; 4 | import com.concurrency.task.PrintQueue; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | // 创建一个打印队列 9 | PrintQueue printQueue = new PrintQueue(); 10 | 11 | // 创建10个打印线程 12 | Thread thread[] = new Thread[10]; 13 | for (int i = 0; i < 10; i++) { 14 | thread[i] = new Thread(new Job(printQueue), "Thread " + i); 15 | } 16 | 17 | // 启动线程 18 | for (int i = 0; i < 10; i++) { 19 | thread[i].start(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /02-05-用锁实现同步/src/com/concurrency/task/Job.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | public class Job implements Runnable { 4 | /** 5 | * 打印文档的队列 6 | */ 7 | private PrintQueue printQueue; 8 | 9 | /** 10 | * 构造函数 11 | * 12 | * @param printQueue 打印文档的队列 13 | */ 14 | public Job(PrintQueue printQueue) { 15 | this.printQueue = printQueue; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | System.out.printf("%s: Going to print a document\n", Thread.currentThread().getName()); 21 | printQueue.printJob(new Object()); 22 | System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /02-05-用锁实现同步/src/com/concurrency/task/PrintQueue.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.locks.Lock; 4 | import java.util.concurrent.locks.ReentrantLock; 5 | 6 | /** 7 | * 打印队列类,模拟一个打印队列事件 8 | */ 9 | public class PrintQueue { 10 | /** 11 | * 用于控制队列访问的锁 12 | */ 13 | private final Lock queueLock = new ReentrantLock(); 14 | 15 | /** 16 | * 打印一个文档 17 | * 18 | * @param object 要打印的文档对象 19 | */ 20 | public void printJob(Object object) { 21 | queueLock.lock(); // 上锁 22 | try { 23 | long duration = (long) (Math.random() * 10000); 24 | System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000)); 25 | Thread.sleep(duration); 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } finally { 29 | queueLock.unlock(); // 解锁 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /02-06-使用读写锁实现同步数据访问/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.PricesInfo; 4 | import com.concurrency.task.Reader; 5 | import com.concurrency.task.Writer; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建价格信息对象,用于存储价格 10 | PricesInfo pricesInfo = new PricesInfo(); 11 | 12 | Reader readers[] = new Reader[5]; 13 | Thread threadsReader[] = new Thread[5]; 14 | 15 | // 创建5个读者并且将其放在不同的线程中远行 16 | for (int i = 0; i < 5; i++) { 17 | readers[i] = new Reader(pricesInfo); 18 | threadsReader[i] = new Thread(readers[i]); 19 | } 20 | 21 | // 创建一个写者,并且将其放在一个线程中运行 22 | Writer writer = new Writer(pricesInfo); 23 | Thread threadWriter = new Thread(writer); 24 | 25 | // 启动读者写者线程 26 | for (int i = 0; i < 5; i++) { 27 | threadsReader[i].start(); 28 | } 29 | threadWriter.start(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /02-06-使用读写锁实现同步数据访问/src/com/concurrency/task/PricesInfo.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.locks.ReadWriteLock; 4 | import java.util.concurrent.locks.ReentrantReadWriteLock; 5 | 6 | /** 7 | * 价格信息类,这个类存储了两个价格,一个写者写这个价格,多个读者读这个价格 8 | */ 9 | public class PricesInfo { 10 | /** 11 | * 两个价格g 12 | */ 13 | private double price1; 14 | private double price2; 15 | 16 | /** 17 | * 控制价格访问的锁 18 | */ 19 | private ReadWriteLock lock; 20 | 21 | /** 22 | * 构造函数,初始化价格和锁 23 | */ 24 | public PricesInfo() { 25 | this.price1 = 1.0; 26 | this.price2 = 2.0; 27 | this.lock = new ReentrantReadWriteLock(); 28 | } 29 | 30 | /** 31 | * 获取第一个价格 32 | * 33 | * @return 第一个价格 34 | */ 35 | public double getPrice1() { 36 | lock.readLock().lock(); 37 | double value = price1; 38 | lock.readLock().unlock(); 39 | return value; 40 | } 41 | 42 | /** 43 | * 获取第二个价格 44 | * 45 | * @return 第二个价格 46 | */ 47 | public double getPrice2() { 48 | lock.readLock().lock(); 49 | double value = price2; 50 | lock.readLock().unlock(); 51 | return value; 52 | } 53 | 54 | /** 55 | * 设置两个价格 56 | * 57 | * @param price1 第一个价格 58 | * @param price2 第二个价格 59 | */ 60 | public void setPrices(double price1, double price2) { 61 | lock.writeLock().lock(); 62 | this.price1 = price1; 63 | this.price2 = price2; 64 | lock.writeLock().unlock(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /02-06-使用读写锁实现同步数据访问/src/com/concurrency/task/Reader.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 读者类,消费价格 5 | */ 6 | public class Reader implements Runnable { 7 | /** 8 | * 价格信息对象 9 | */ 10 | private PricesInfo pricesInfo; 11 | 12 | /** 13 | * 构造函数 14 | * 15 | * @param pricesInfo 价格信息对象 16 | */ 17 | public Reader(PricesInfo pricesInfo) { 18 | this.pricesInfo = pricesInfo; 19 | } 20 | 21 | /** 22 | * 核心方法,消费两个价格,并且将他们输出 23 | */ 24 | @Override 25 | public void run() { 26 | for (int i = 0; i < 10; i++) { 27 | System.out.printf("%s: Price 1: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice1()); 28 | System.out.printf("%s: Price 2: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice2()); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /02-06-使用读写锁实现同步数据访问/src/com/concurrency/task/Writer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 写者类,产生价格 5 | */ 6 | public class Writer implements Runnable { 7 | /** 8 | * 价格信息对象 9 | */ 10 | private PricesInfo pricesInfo; 11 | 12 | /** 13 | * 构造函数 14 | * 15 | * @param pricesInfo 价格信息对象 16 | */ 17 | public Writer(PricesInfo pricesInfo) { 18 | this.pricesInfo = pricesInfo; 19 | } 20 | 21 | /** 22 | * 核心方法,写价格 23 | */ 24 | @Override 25 | public void run() { 26 | for (int i = 0; i < 3; i++) { 27 | System.out.printf("Writer: Attempt to modify the prices.\n"); 28 | pricesInfo.setPrices(Math.random() * 10, Math.random() * 8); 29 | System.out.printf("Writer: Prices have been modified.\n"); 30 | try { 31 | Thread.sleep(2); 32 | } catch (InterruptedException e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /02-07-修改锁的公平性/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Job; 4 | import com.concurrency.task.PrintQueue; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | // 创建一个打印队列 9 | PrintQueue printQueue = new PrintQueue(); 10 | 11 | // 创建10个打印任务并且将其放入到不同的线程中运行 12 | Thread thread[] = new Thread[10]; 13 | for (int i = 0; i < 10; i++) { 14 | thread[i] = new Thread(new Job(printQueue), "Thread " + i); 15 | } 16 | 17 | // 每隔0.1s运行一个线程,一个10个线程 18 | for (int i = 0; i < 10; i++) { 19 | thread[i].start(); 20 | try { 21 | Thread.sleep(100); 22 | } catch (InterruptedException e) { 23 | e.printStackTrace(); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /02-07-修改锁的公平性/src/com/concurrency/task/Job.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | 4 | public class Job implements Runnable { 5 | /** 6 | * 打印文档的队列 7 | */ 8 | private PrintQueue printQueue; 9 | 10 | /** 11 | * 构造函数 12 | * 13 | * @param printQueue 打印文档的队列 14 | */ 15 | public Job(PrintQueue printQueue) { 16 | this.printQueue = printQueue; 17 | } 18 | 19 | @Override 20 | public void run() { 21 | System.out.printf("%s: Going to print a document\n", Thread.currentThread().getName()); 22 | printQueue.printJob(new Object()); 23 | System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /02-07-修改锁的公平性/src/com/concurrency/task/PrintQueue.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.locks.Lock; 4 | import java.util.concurrent.locks.ReentrantLock; 5 | 6 | /** 7 | * 打印队列类,模拟一个打印队列事件 8 | */ 9 | public class PrintQueue { 10 | /** 11 | * 用于控制队列访问的锁,使用公平锁 12 | */ 13 | private final Lock queueLock = new ReentrantLock(false); 14 | 15 | /** 16 | * 打印一个文档 17 | * 18 | * @param object 要打印的文档对象 19 | */ 20 | public void printJob(Object object) { 21 | queueLock.lock(); // 上锁 22 | try { 23 | long duration = (long) (Math.random() * 10000); 24 | System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000)); 25 | Thread.sleep(duration); 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } finally { 29 | queueLock.unlock(); // 解锁 30 | } 31 | 32 | queueLock.lock(); // 上锁 33 | try { 34 | long duration = (long) (Math.random() * 10000); 35 | System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), (duration / 1000)); 36 | Thread.sleep(duration); 37 | } catch (InterruptedException e) { 38 | e.printStackTrace(); 39 | } finally { 40 | queueLock.unlock(); // 解锁 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /02-08-在锁中使用多条件/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Consumer; 4 | import com.concurrency.task.Producer; 5 | import com.concurrency.utils.Buffer; 6 | import com.concurrency.utils.FileMock; 7 | 8 | public class Main { 9 | public static void main(String[] args) { 10 | // 创建一个文件模拟对象,它有101行 11 | FileMock mock = new FileMock(101, 10); 12 | 13 | // 创建一个缓冲对象,最多可以缓存20行数据 14 | Buffer buffer = new Buffer(20); 15 | 16 | // 创建一个生产者对象,并且让它在一个单独的线程中运行 17 | Producer producer = new Producer(mock, buffer); 18 | Thread threadProducer = new Thread(producer, "Producer"); 19 | 20 | // 创建三个消费者对象,并且个他们分别在不同的线程中运行 21 | Consumer consumers[] = new Consumer[3]; 22 | Thread threadConsumers[] = new Thread[3]; 23 | 24 | for (int i = 0; i < 3; i++) { 25 | consumers[i] = new Consumer(buffer); 26 | threadConsumers[i] = new Thread(consumers[i], "Consumer " + i); 27 | } 28 | 29 | // 启动生产者和消费者线程 30 | threadProducer.start(); 31 | for (int i = 0; i < 3; i++) { 32 | threadConsumers[i].start(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /02-08-在锁中使用多条件/src/com/concurrency/task/Consumer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.utils.Buffer; 4 | 5 | import java.util.Random; 6 | 7 | public class Consumer implements Runnable { 8 | /** 9 | * 缓冲对象 10 | */ 11 | private Buffer buffer; 12 | 13 | /** 14 | * 构造函数 15 | * 16 | * @param buffer 缓冲对象 17 | */ 18 | public Consumer(Buffer buffer) { 19 | this.buffer = buffer; 20 | } 21 | 22 | /** 23 | * 核心方法,当缓冲中有数据时就进行处理 24 | */ 25 | @Override 26 | public void run() { 27 | while (buffer.hasPendingLines()) { 28 | String line = buffer.get(); 29 | processLine(line); 30 | } 31 | } 32 | 33 | /** 34 | * 模拟处理一行数据,休眠[0,100)毫秒 35 | * 36 | * @param line 一行数据 37 | */ 38 | private void processLine(String line) { 39 | try { 40 | Random random = new Random(); 41 | Thread.sleep(random.nextInt(100)); 42 | } catch (InterruptedException e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /02-08-在锁中使用多条件/src/com/concurrency/task/Producer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.utils.Buffer; 4 | import com.concurrency.utils.FileMock; 5 | 6 | public class Producer implements Runnable { 7 | /** 8 | * 文件模拟对象 9 | */ 10 | private FileMock mock; 11 | /** 12 | * 缓冲对象 13 | */ 14 | private Buffer buffer; 15 | 16 | /** 17 | * 构造函数 18 | * 19 | * @param mock 文件模拟对象 20 | * @param buffer 缓冲对象 21 | */ 22 | public Producer(FileMock mock, Buffer buffer) { 23 | this.mock = mock; 24 | this.buffer = buffer; 25 | } 26 | 27 | /** 28 | * 核心方法,读取文件中的数据,并且将读取到的数据插入到缓冲区 29 | */ 30 | @Override 31 | public void run() { 32 | this.buffer.setPendingLines(true); 33 | while (this.mock.hasMoreLines()) { 34 | String line = this.mock.getLine(); 35 | this.buffer.insert(line); 36 | } 37 | this.buffer.setPendingLines(false); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /02-08-在锁中使用多条件/src/com/concurrency/utils/Buffer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.utils; 2 | 3 | import java.util.LinkedList; 4 | import java.util.concurrent.locks.Condition; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | public class Buffer { 8 | /** 9 | * 集合对象,被当作缓冲使用 10 | */ 11 | private LinkedList buffer; 12 | /** 13 | * 缓冲的最大大小 14 | */ 15 | private int maxSize; 16 | /** 17 | * 控制缓冲访问的锁 18 | */ 19 | private ReentrantLock lock; 20 | /** 21 | * 缓冲中有数据的条件 22 | */ 23 | private Condition lines; 24 | /** 25 | * 缓冲为空的条件 26 | */ 27 | private Condition space; 28 | /** 29 | * 是否追加行 30 | */ 31 | private boolean pendingLines; 32 | 33 | /** 34 | * 构造函数,初始化属性 35 | * 36 | * @param maxSize 缓冲最大大小 37 | */ 38 | public Buffer(int maxSize) { 39 | this.maxSize = maxSize; 40 | this.buffer = new LinkedList<>(); 41 | this.lock = new ReentrantLock(); 42 | this.lines = lock.newCondition(); 43 | this.space = lock.newCondition(); 44 | this.pendingLines = true; 45 | } 46 | 47 | /** 48 | * 向缓冲区中插入一行数据 49 | * 50 | * @param line 一行数据 51 | */ 52 | public void insert(String line) { 53 | lock.lock(); 54 | try { 55 | while (this.buffer.size() == this.maxSize) { 56 | this.space.await(); 57 | } 58 | 59 | this.buffer.offer(line); 60 | System.out.printf("%s: Inserted Line: %d\n", Thread.currentThread().getName(), this.buffer.size()); 61 | this.lines.signalAll(); 62 | } catch (InterruptedException e) { 63 | e.printStackTrace(); 64 | } finally { 65 | lock.unlock(); 66 | } 67 | } 68 | 69 | public String get() { 70 | String line = null; 71 | lock.lock(); 72 | try { 73 | while (this.buffer.size() == 0 && hasPendingLines()) { 74 | this.lines.await(); 75 | } 76 | 77 | if (hasPendingLines()) { 78 | line = this.buffer.poll(); 79 | System.out.printf("%s: Line Readed: %d\n", Thread.currentThread().getName(), this.buffer.size()); 80 | this.space.signalAll(); 81 | } 82 | 83 | } catch (InterruptedException e) { 84 | e.printStackTrace(); 85 | } finally { 86 | this.lock.unlock(); 87 | } 88 | 89 | return line; 90 | } 91 | 92 | /** 93 | * 设置是否追加行 94 | * 95 | * @param pendingLines true追加,false不追加 96 | */ 97 | public void setPendingLines(boolean pendingLines) { 98 | this.pendingLines = pendingLines; 99 | } 100 | 101 | /** 102 | * 判断是否有数据可以进行处理 103 | * 104 | * @return true有数据可进行处理,false无数据可以进行处理 105 | */ 106 | public boolean hasPendingLines() { 107 | return this.pendingLines || this.buffer.size() > 0; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /02-08-在锁中使用多条件/src/com/concurrency/utils/FileMock.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.utils; 2 | 3 | /** 4 | * 文件模拟类, 5 | */ 6 | public class FileMock { 7 | /** 8 | * 模拟文件的内容 9 | */ 10 | private String[] content; 11 | /** 12 | * 当前需要处理的文件第多少行 13 | */ 14 | private int index; 15 | 16 | /** 17 | * 构造函数,随机生成文件的内容 18 | * 19 | * @param size 文件的行数 20 | * @param length 每行文件的字符数 21 | */ 22 | public FileMock(int size, int length) { 23 | this.content = new String[size]; 24 | for (int i = 0; i < size; i++) { 25 | StringBuilder builder = new StringBuilder(length); 26 | for (int j = 0; j < length; j++) { 27 | int indice = (int) (Math.random() * 255); 28 | builder.append((char) indice); 29 | } 30 | content[i] = builder.toString(); 31 | } 32 | this.index = 0; 33 | } 34 | 35 | /** 36 | * 判断是否还有文件的行数需要处理 37 | * 38 | * @return true是,false否 39 | */ 40 | public boolean hasMoreLines() { 41 | return this.index < this.content.length; 42 | } 43 | 44 | /** 45 | * 返回下一行的文件内容 46 | * 47 | * @return 有返回文件内容,没有返回false 48 | */ 49 | public String getLine() { 50 | if (this.hasMoreLines()) { 51 | System.out.println("Mock: " + (this.content.length - this.index)); 52 | return this.content[this.index++]; 53 | } 54 | return null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /02-09-应用例子/src/com.concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.BuildStats; 4 | import com.concurrency.task.Sensor1; 5 | import com.concurrency.task.Sensor2; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * Author: 王俊超 11 | * Date: 2014-11-23 12 | * Time: 08:38 13 | * Declaration: All Rights Reserved !!! 14 | */ 15 | public class Main { 16 | public static void main(String[] args) { 17 | // 创建一个建筑物状态对象 18 | BuildStats stats = new BuildStats(); 19 | 20 | // 创建场景1对象,并且让它在一个单独的线程中运行 21 | Sensor1 sensor1 = new Sensor1(stats); 22 | Thread thread1 = new Thread(sensor1, "Sensor 1"); 23 | 24 | // 创建场景2对象,并且让它在一个单独的线程中运行 25 | Sensor2 sensor2 = new Sensor2(stats); 26 | Thread thread2 = new Thread(sensor2, "Sensor 2"); 27 | 28 | // 获取实际时间 29 | Date date1 = new Date(); 30 | 31 | // 启动线程 32 | thread1.start(); 33 | thread2.start(); 34 | 35 | try { 36 | // 等待线程完成 37 | thread1.join(); 38 | thread2.join(); 39 | } catch (InterruptedException e) { 40 | e.printStackTrace(); 41 | } 42 | 43 | // 获取实际时间,并且输出实际时间 44 | Date date2 = new Date(); 45 | stats.printStats(); 46 | System.out.println("Execution Time: " + ((date2.getTime() - date1.getTime()) / 1000)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /02-09-应用例子/src/com.concurrency/task/BuildStats.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | /** 6 | * 建筑物状态类,对进入其中的人进行统计,并且控制建筑物中的人数 7 | * Author: 王俊超 8 | * Date: 2014-11-25 9 | * Time: 07:51 10 | * Declaration: All Rights Reserved !!! 11 | */ 12 | public class BuildStats { 13 | /** 14 | * 建筑物中的人数 15 | */ 16 | private long numPeople; 17 | 18 | /** 19 | * 模拟人进入到建筑物中 20 | */ 21 | public void comeIn() { 22 | System.out.printf("%s: A person enters.\n", Thread.currentThread().getName()); 23 | synchronized (this) { 24 | numPeople++; 25 | } 26 | generateCard(); 27 | } 28 | 29 | /** 30 | * 模拟人从建筑物中走出来 31 | */ 32 | public void goOut() { 33 | System.out.printf("%s: A person leaves.\n", Thread.currentThread().getName()); 34 | synchronized (this) { 35 | numPeople--; 36 | } 37 | generateReport(); 38 | } 39 | 40 | /** 41 | * 当人进入建筑物中时,会模拟产生一张卡 42 | */ 43 | private void generateCard() { 44 | try { 45 | TimeUnit.SECONDS.sleep(3); 46 | } catch (InterruptedException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | 51 | /** 52 | * 当人离开建筑物时,会模拟产生一个报告 53 | */ 54 | private void generateReport() { 55 | try { 56 | TimeUnit.SECONDS.sleep(2); 57 | } catch (InterruptedException e) { 58 | e.printStackTrace(); 59 | } 60 | } 61 | 62 | /** 63 | * 输入建筑物中的人数 64 | */ 65 | public void printStats() { 66 | System.out.printf("%d persons in the building.\n", numPeople); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /02-09-应用例子/src/com.concurrency/task/Sensor1.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * Author: 王俊超 5 | * Date: 2014-11-25 6 | * Time: 07:59 7 | * Declaration: All Rights Reserved !!! 8 | */ 9 | public class Sensor1 implements Runnable { 10 | /** 11 | * 建筑物状态对象 12 | */ 13 | private BuildStats stats; 14 | 15 | /** 16 | * 构造函数 17 | * 18 | * @param stats 建筑物状态对象 19 | */ 20 | public Sensor1(BuildStats stats) { 21 | this.stats = stats; 22 | } 23 | 24 | /** 25 | * 核心方法,模拟人在建筑物中的进出 26 | */ 27 | @Override 28 | public void run() { 29 | stats.comeIn(); 30 | stats.comeIn(); 31 | stats.comeIn(); 32 | stats.goOut(); 33 | stats.comeIn(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /02-09-应用例子/src/com.concurrency/task/Sensor2.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * Author: 王俊超 5 | * Date: 2014-11-25 6 | * Time: 07:59 7 | * Declaration: All Rights Reserved !!! 8 | */ 9 | public class Sensor2 implements Runnable { 10 | /** 11 | * 建筑物状态对象 12 | */ 13 | private BuildStats stats; 14 | 15 | /** 16 | * 构造函数 17 | * 18 | * @param stats 建筑物状态对象 19 | */ 20 | public Sensor2(BuildStats stats) { 21 | this.stats = stats; 22 | } 23 | 24 | /** 25 | * 核心方法,模拟人在建筑物中的进出 26 | */ 27 | @Override 28 | public void run() { 29 | stats.comeIn(); 30 | stats.comeIn(); 31 | stats.goOut(); 32 | stats.goOut(); 33 | stats.goOut(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /03-02-资源并发控制访问/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Job; 4 | import com.concurrency.task.PrintQueue; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | // 创建一个打印队列对象 9 | PrintQueue printQueue = new PrintQueue(); 10 | 11 | // 创建10个线程 12 | Thread thread[] = new Thread[10]; 13 | for (int i = 0; i < 10; i++) { 14 | thread[i] = new Thread(new Job(printQueue), "Thread " + i); 15 | } 16 | 17 | // 启动10个线程 18 | for (int i = 0; i < 10; i++) { 19 | thread[i].start(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /03-02-资源并发控制访问/src/com/concurrency/task/Job.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | public class Job implements Runnable { 4 | /** 5 | * 打印队列对象 6 | */ 7 | private PrintQueue printQueue; 8 | 9 | /** 10 | * 构造函数,初始化打印队列对象 11 | * 12 | * @param printQueue 打印队列对象 13 | */ 14 | public Job(PrintQueue printQueue) { 15 | this.printQueue = printQueue; 16 | } 17 | 18 | /** 19 | * 核心方法,向打印队列中发送打印任务,并且等待它完成 20 | */ 21 | @Override 22 | public void run() { 23 | System.out.printf("%s: Going to print a job\n", Thread.currentThread().getName()); 24 | printQueue.printJob(new Object()); 25 | System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /03-02-资源并发控制访问/src/com/concurrency/task/PrintQueue.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.core.Main; 4 | 5 | import java.util.concurrent.Semaphore; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * 打印队列类,使用信号量来控制打钱作业的访问 10 | */ 11 | public class PrintQueue { 12 | /** 13 | * 信号量,控制队列的访问 14 | */ 15 | private final Semaphore semaphore; 16 | 17 | /** 18 | * 构造函数,初始化信号量 19 | */ 20 | public PrintQueue() { 21 | semaphore = new Semaphore(1); 22 | } 23 | 24 | /** 25 | * 模拟文档打印的方法 26 | * 27 | * @param document 需要打印的对象 28 | */ 29 | public void printJob(Object document) { 30 | try { 31 | // 请求信号量,如果已经被其它线程请求过,则当前请求的线程会休眠,直到获得这个信号量 32 | semaphore.acquire(); 33 | 34 | long duration = (long) (Math.random() * 10); 35 | System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), duration); 36 | Thread.sleep(duration); 37 | TimeUnit.SECONDS.sleep(duration); 38 | } catch (InterruptedException e) { 39 | e.printStackTrace(); 40 | } finally { 41 | // 释放信号量,如果有其它的线程在请求这个信号量,JVN会选择其中的某一个程获取信号量,让其运行 42 | semaphore.release(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /03-03-资源的多副本的并发访问控制/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Job; 4 | import com.concurrency.task.PrintQueue; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | // 创建一个打印对队对象 9 | PrintQueue printQueue = new PrintQueue(); 10 | 11 | // 创建12个线程,运行作业任务,这些任务都向同一个打印队列对象发出打印请求 12 | Thread thread[] = new Thread[12]; 13 | for (int i = 0; i < 12; i++) { 14 | thread[i] = new Thread(new Job(printQueue), "Thread " + i); 15 | } 16 | 17 | // 启动12个线程 18 | for (int i = 0; i < 12; i++) { 19 | thread[i].start(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /03-03-资源的多副本的并发访问控制/src/com/concurrency/task/Job.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | public class Job implements Runnable { 4 | /** 5 | * 打印队列对象 6 | */ 7 | private PrintQueue printQueue; 8 | 9 | /** 10 | * 构造函数,初始化打印队列对象 11 | * 12 | * @param printQueue 打印队列对象 13 | */ 14 | public Job(PrintQueue printQueue) { 15 | this.printQueue = printQueue; 16 | } 17 | 18 | /** 19 | * 核心方法,向打印队列中发送打印任务,并且等待它完成 20 | */ 21 | @Override 22 | public void run() { 23 | System.out.printf("%s: Going to print a job\n", Thread.currentThread().getName()); 24 | printQueue.printJob(new Object()); 25 | System.out.printf("%s: The document has been printed\n", Thread.currentThread().getName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /03-03-资源的多副本的并发访问控制/src/com/concurrency/task/PrintQueue.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Semaphore; 4 | import java.util.concurrent.TimeUnit; 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | /** 9 | * 打印队列对象,它可以访问三台打印机,使用信号量来控制打印机的访问,当有一个打印作业, 10 | * 如果有空闲的打印杨就将作业分配到某个打印机上,否则就等待打印机空闲,再分配打印机 11 | */ 12 | public class PrintQueue { 13 | /** 14 | * 资源信号量,控制打印机的访问 15 | */ 16 | private Semaphore semaphore; 17 | /** 18 | * 标记打印机是否空闲的数组 19 | */ 20 | private boolean[] freePrinters; 21 | /** 22 | * 锁,控制打印机是否空闲的数组的访问 23 | */ 24 | private Lock lockPrinters; 25 | 26 | /** 27 | * 构造函数,初始化变量 28 | */ 29 | public PrintQueue() { 30 | semaphore = new Semaphore(3); // 资源信号量的个数为3,说明有3个打印机 31 | freePrinters = new boolean[3]; 32 | for (int i = 0; i < freePrinters.length; i++) { 33 | freePrinters[i] = true; 34 | } 35 | 36 | lockPrinters = new ReentrantLock(); 37 | } 38 | 39 | /** 40 | * 模拟文档打印的方法 41 | * 42 | * @param document 需要打印的对象 43 | */ 44 | public void printJob(Object document) { 45 | try { 46 | // 请求信号量,如果有一个打印机是空闲的,就会访问其中一个空闲的打印机 47 | semaphore.acquire(); 48 | 49 | // 获取分配的打印机编号 50 | int assignedPrinter = getPrinter(); 51 | 52 | Long duration = (long) (Math.random() * 10); 53 | System.out.printf("%s: PrintQueue: Printing a Job in Printer %d during %d seconds\n", Thread.currentThread().getName(), assignedPrinter, duration); 54 | TimeUnit.SECONDS.sleep(duration); 55 | 56 | // 释放打印机 57 | freePrinters[assignedPrinter] = true; 58 | } catch (InterruptedException e) { 59 | e.printStackTrace(); 60 | } finally { 61 | // 释放信号量 62 | semaphore.release(); 63 | } 64 | } 65 | 66 | /** 67 | * 获取分配的打印机编号 68 | * @return 分配的打印机编号 69 | */ 70 | private int getPrinter() { 71 | int ret = -1; 72 | try { 73 | // 获取打印机状态数组的访问能力 74 | lockPrinters.lock(); 75 | // 查找第一个空闲的打印机 76 | for (int i = 0; i < freePrinters.length; i++) { 77 | if (freePrinters[i]) { 78 | ret = i; 79 | freePrinters[i] = false; 80 | break; 81 | } 82 | } 83 | } catch (Exception e) { 84 | e.printStackTrace(); 85 | } finally { 86 | // 释放打印机状态数组的访问能力 87 | lockPrinters.unlock(); 88 | } 89 | return ret; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /03-04-等待多个并发事件的完成/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Participant; 4 | import com.concurrency.task.VideoConference; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | // 创建一个视频会议对象,它有10个参与者 9 | VideoConference conference = new VideoConference(10); 10 | // 创建一个线程去运行视频会议 11 | Thread threadConference = new Thread(conference); 12 | threadConference.start(); 13 | 14 | // 创建十个参与者,每个参与者在一个单独的线程中运行 15 | for (int i = 0; i < 10; i++) { 16 | Participant p = new Participant(conference, "Participant " + i); 17 | Thread t = new Thread(p); 18 | t.start(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /03-04-等待多个并发事件的完成/src/com/concurrency/task/Participant.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | /** 6 | * 参与者类 7 | */ 8 | public class Participant implements Runnable { 9 | /** 10 | * 视频会议对象 11 | */ 12 | private VideoConference conference; 13 | /** 14 | * 参与者的名称(仅仅是为了记录使用) 15 | */ 16 | private String name; 17 | 18 | /** 19 | * 构造函数 20 | * 21 | * @param conference 视频会议对象 22 | * @param name 参与者的名称 23 | */ 24 | public Participant(VideoConference conference, String name) { 25 | this.conference = conference; 26 | this.name = name; 27 | } 28 | 29 | 30 | /** 31 | * 核心方法,等待一个随机时间就进入视频会议 32 | */ 33 | @Override 34 | public void run() { 35 | long duration = (long) (Math.random() * 10); 36 | try { 37 | TimeUnit.SECONDS.sleep(duration); 38 | } catch (InterruptedException e) { 39 | e.printStackTrace(); 40 | } 41 | conference.arrive(name); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /03-04-等待多个并发事件的完成/src/com/concurrency/task/VideoConference.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | 5 | /** 6 | * 视频会类 7 | * 使用倒计时闩来控制所有参与者都到达后才发生事件 8 | */ 9 | public class VideoConference implements Runnable { 10 | /** 11 | * 倒计时闩对象 12 | */ 13 | private final CountDownLatch controller; 14 | 15 | /** 16 | * 构造函数,初始化倒计时闩 17 | * @param number 参与者人数 18 | */ 19 | public VideoConference(int number) { 20 | controller = new CountDownLatch(number); 21 | } 22 | 23 | /** 24 | * 每个参与到视频会议的都会调用此方法 25 | * @param name 参与者 26 | */ 27 | public void arrive(String name) { 28 | System.out.printf("%s has arrived.\n", name); 29 | controller.countDown(); 30 | System.out.printf("VideoConference: Waiting for %d participants.\n", controller.getCount()); 31 | } 32 | 33 | /** 34 | * 核心方法,当所有参与者都到达了,就开始视频仁义 35 | */ 36 | @Override 37 | public void run() { 38 | System.out.printf("VideoConference: Initialization: %d participants.\n", controller.getCount()); 39 | try { 40 | // Wait for all the participants 41 | controller.await(); 42 | // Starts the conference 43 | System.out.printf("VideoConference: All the participants have come\n"); 44 | System.out.printf("VideoConference: Let's start...\n"); 45 | } catch (InterruptedException e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /03-05-在集合点的同步/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Grouper; 4 | import com.concurrency.task.Searcher; 5 | import com.concurrency.utils.MatrixMock; 6 | import com.concurrency.utils.Results; 7 | 8 | import java.util.concurrent.CyclicBarrier; 9 | 10 | public class Main { 11 | public static void main(String[] args) { 12 | 13 | final int ROWS = 10000; // 矩阵的行数 14 | final int NUMBERS = 1000; // 矩阵的列数 15 | final int SEARCH = 5; // 要查询的数字 16 | final int PARTICIPANTS = 5; // 查询线程的个数 17 | final int LINES_PARTICIPANT = 2000; // 每个查询线程处理的行数 18 | MatrixMock mock = new MatrixMock(ROWS, NUMBERS, SEARCH); // 创建矩阵模拟对象 19 | Results results = new Results(ROWS); // 创建结果对象 20 | Grouper grouper = new Grouper(results); // 创建组合对象 21 | 22 | // 创建一个同步栅对象,它有5个参与者, 5个参与者线程完成后,会调用grouper中的run方法 23 | CyclicBarrier barrier = new CyclicBarrier(PARTICIPANTS, grouper); 24 | 25 | // 创建5个参与者对象,并且让它们各自在单独的线程中运行 26 | Searcher[] searchers = new Searcher[PARTICIPANTS]; 27 | for (int i = 0; i < searchers.length; i++) { 28 | searchers[i] = new Searcher(barrier, i * LINES_PARTICIPANT, (i * LINES_PARTICIPANT) + LINES_PARTICIPANT, 29 | mock, results, PARTICIPANTS); 30 | 31 | Thread thread = new Thread(searchers[i]); 32 | thread.start(); 33 | } 34 | System.out.printf("Main: The main thread has finished.\n"); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /03-05-在集合点的同步/src/com/concurrency/task/Grouper.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.utils.Results; 4 | 5 | /** 6 | * 组合类,汇总查找的结果 7 | */ 8 | public class Grouper implements Runnable { 9 | /** 10 | * 结果对象 11 | */ 12 | private Results results; 13 | 14 | /** 15 | * 构造函数 16 | * 17 | * @param results 结果对象 18 | */ 19 | public Grouper(Results results) { 20 | this.results = results; 21 | } 22 | 23 | /** 24 | * 核心方法,对查找的结果进行汇总 25 | */ 26 | @Override 27 | public void run() { 28 | int finalResult = 0; 29 | System.out.printf("Grouper: Processing results...\n"); 30 | int data[] = results.getData(); 31 | for (int number : data) { 32 | finalResult += number; 33 | } 34 | System.out.printf("Grouper: Total result: %d.\n", finalResult); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /03-05-在集合点的同步/src/com/concurrency/task/Searcher.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.utils.MatrixMock; 4 | import com.concurrency.utils.Results; 5 | 6 | import java.util.concurrent.BrokenBarrierException; 7 | import java.util.concurrent.CyclicBarrier; 8 | 9 | /** 10 | * 查找类 11 | */ 12 | public class Searcher implements Runnable { 13 | /** 14 | * 开始查找的行数 15 | */ 16 | private int firstRow; 17 | /** 18 | * 最后查找的行数(不包含) 19 | */ 20 | private int lastRow; 21 | /** 22 | * 矩阵模拟对象 23 | */ 24 | private MatrixMock mock; 25 | /** 26 | * 结果对象 27 | */ 28 | private Results results; 29 | /** 30 | * 要查找的数字 31 | */ 32 | private int number; 33 | /** 34 | * 同步栅 35 | */ 36 | private final CyclicBarrier barrier; 37 | 38 | /** 39 | * 构造函数 40 | * 41 | * @param barrier 同步栅 42 | * @param firstRow 开始查找的行数 43 | * @param lastRow 最后查找的行数(不包含) 44 | * @param mock 矩阵模拟对象 45 | * @param results 结果对象 46 | * @param number 要查找的数字 47 | */ 48 | public Searcher(CyclicBarrier barrier, int firstRow, int lastRow, MatrixMock mock, Results results, int number) { 49 | this.barrier = barrier; 50 | this.firstRow = firstRow; 51 | this.lastRow = lastRow; 52 | this.mock = mock; 53 | this.results = results; 54 | this.number = number; 55 | } 56 | 57 | /** 58 | * 核心方法,查找指定行数范围内的指定数字,将结果保存在结果数组对应的位置 59 | */ 60 | @Override 61 | public void run() { 62 | int counter; 63 | System.out.printf("%s: Processing lines from %d to %d.\n", Thread.currentThread().getName(), firstRow, lastRow); 64 | for (int i = firstRow; i < lastRow; i++) { 65 | int row[] = mock.getRow(i); 66 | counter = 0; 67 | for (int j = 0; j < row.length; j++) { 68 | if (row[j] == number) { 69 | counter++; 70 | } 71 | } 72 | 73 | results.setData(i, counter); 74 | } 75 | 76 | System.out.printf("%s: Lines processed.\n", Thread.currentThread().getName()); 77 | try { 78 | barrier.await(); // 等待所有查找完成 79 | } catch (InterruptedException e) { 80 | e.printStackTrace(); 81 | } catch (BrokenBarrierException e) { 82 | e.printStackTrace(); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /03-05-在集合点的同步/src/com/concurrency/utils/MatrixMock.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.utils; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * 矩阵模拟类,随机生成0-9之间数字二维矩 7 | */ 8 | public class MatrixMock { 9 | /** 10 | * 0-9之间数字二维矩阵 11 | */ 12 | private int[][] data; 13 | 14 | /** 15 | * 构造函数 16 | * 17 | * @param size 矩阵的行数 18 | * @param length 每行的长度 19 | * @param number 要查找的数字 20 | */ 21 | public MatrixMock(int size, int length, int number) { 22 | int counter = 0; 23 | data = new int[size][length]; 24 | Random random = new Random(); 25 | for (int i = 0; i < size; i++) { 26 | for (int j = 0; j < length; j++) { 27 | data[i][j] = random.nextInt(10); 28 | if (data[i][j] == number) { 29 | counter++; 30 | } 31 | } 32 | } 33 | 34 | System.out.printf("Mock: There are %d ocurrences of number in generated data.\n", counter, number); 35 | } 36 | 37 | /** 38 | * 获取行row行数据 39 | * 40 | * @param row 行数 41 | * @return 第row行数据,没有就返回null 42 | */ 43 | public int[] getRow(int row) { 44 | if (row >= 0 && row < data.length) { 45 | return data[row]; 46 | } 47 | 48 | return null; 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /03-05-在集合点的同步/src/com/concurrency/utils/Results.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.utils; 2 | 3 | /** 4 | * 结果类,保存矩阵中每行找到指定数字的次数 5 | */ 6 | public class Results { 7 | /** 8 | * 保存矩阵中每行找到指定数字的次数 9 | */ 10 | private int[] data; 11 | 12 | /** 13 | * 构造函数 14 | * 15 | * @param size 数组长度 16 | */ 17 | public Results(int size) { 18 | this.data = new int[size]; 19 | } 20 | 21 | /** 22 | * 设置数组的值 23 | * 24 | * @param position 位置 25 | * @param value 要设置的值 26 | */ 27 | public void setData(int position, int value) { 28 | data[position] = value; 29 | } 30 | 31 | /** 32 | * 获取保存的数据 33 | * 34 | * @return 保存的数据 35 | */ 36 | public int[] getData() { 37 | return data; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /03-06-并发阶段任务的运行/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.FileSearch; 4 | 5 | import java.util.concurrent.Phaser; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建一个阶段对象,它有三个参与者 10 | Phaser phaser = new Phaser(3); 11 | 12 | // 创建一个文件搜索对象,每一个搜索不同的目录 13 | FileSearch system = new FileSearch("C:\\Windows", "log", phaser); 14 | FileSearch apps = new FileSearch("C:\\Program Files", "log", phaser); 15 | FileSearch documents = new FileSearch("C:\\Documents And Settings", "log", phaser); 16 | 17 | // 创建一个线程运行文件搜索对象,并且启动线程 18 | Thread systemThread = new Thread(system, "System"); 19 | systemThread.start(); 20 | 21 | // 创建一个线程运行文件搜索对象,并且启动线程 22 | Thread appsThread = new Thread(apps, "Apps"); 23 | appsThread.start(); 24 | 25 | // 创建一个线程运行文件搜索对象,并且启动线程 26 | Thread documentsThread = new Thread(documents, "Documents"); 27 | documentsThread.start(); 28 | 29 | // 等待所有的线程都结束 30 | try { 31 | systemThread.join(); 32 | appsThread.join(); 33 | documentsThread.join(); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | 38 | System.out.printf("Terminated: %s\n", phaser.isTerminated()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /03-07-并发阶段任务中的阶段切换/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.MyPhaser; 4 | import com.concurrency.task.Student; 5 | 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建一个阶段对象 10 | MyPhaser phaser = new MyPhaser(); 11 | // 创建一个学生对象,将它们注册到同一个阶段对象中 12 | Student[] students = new Student[5]; 13 | for (int i = 0; i < students.length; i++) { 14 | students[i] = new Student(phaser); 15 | phaser.register(); 16 | } 17 | 18 | // 创建五个线程来运行五个学生对象,并且启动线程 19 | Thread[] threads = new Thread[5]; 20 | for (int i = 0; i < students.length; i++) { 21 | threads[i] = new Thread(students[i]); 22 | threads[i].start(); 23 | } 24 | 25 | // 等待所有线程完成执行 26 | try { 27 | for (int i = 0; i < threads.length; i++) { 28 | threads[i].join(); 29 | } 30 | } catch (InterruptedException e) { 31 | e.printStackTrace(); 32 | } 33 | 34 | // 检查阶段是否已经到达完成状态 35 | System.out.printf("Main: The phaser has finished: %s.\n", phaser.isTerminated()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /03-07-并发阶段任务中的阶段切换/src/com/concurrency/task/MyPhaser.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Phaser; 4 | 5 | /** 6 | * 线程阶段类,控制线程阶段的改变 7 | */ 8 | public class MyPhaser extends Phaser { 9 | /** 10 | * @param phase 实际的阶段 11 | * @param registeredParties 注册的线程数 12 | * @return false表明要进一步执行,true表明已经完成 13 | */ 14 | @Override 15 | protected boolean onAdvance(int phase, int registeredParties) { 16 | switch (phase) { 17 | case 0: 18 | return studentArrived(); 19 | case 1: 20 | return finishFirstExercise(); 21 | case 2: 22 | return finishSecondExercise(); 23 | case 3: 24 | return finishExam(); 25 | default: 26 | return true; 27 | } 28 | } 29 | 30 | /** 31 | * 从0->1阶段改变时调用这个方法 32 | * 33 | * @return 总是返回false,表明还要断续执行 34 | */ 35 | private boolean studentArrived() { 36 | System.out.printf("Phaser: The exam are going to start. The students are ready.\n"); 37 | System.out.printf("Phaser: We have %d students.\n", getRegisteredParties()); 38 | return false; 39 | } 40 | 41 | /** 42 | * 从1->2阶段改变时调用这个方法 43 | * 44 | * @return 总是返回false,表明还要断续执行 45 | */ 46 | private boolean finishFirstExercise() { 47 | System.out.printf("Phaser: All the students has finished the first exercise.\n"); 48 | System.out.printf("Phaser: It's turn for the second one.\n"); 49 | return false; 50 | } 51 | 52 | /** 53 | * 从2->3阶段改变时调用这个方法 54 | * 55 | * @return 总是返回false,表明还要断续执行 56 | */ 57 | private boolean finishSecondExercise() { 58 | System.out.printf("Phaser: All the students has finished the second exercise.\n"); 59 | System.out.printf("Phaser: It's turn for the third one.\n"); 60 | return false; 61 | } 62 | 63 | /** 64 | * 从3->4阶段改变时调用这个方法 65 | * 66 | * @return 总是返回false,表明还要断续执行 67 | */ 68 | private boolean finishExam() { 69 | System.out.printf("Phaser: All the students has finished the exam.\n"); 70 | System.out.printf("Phaser: Thank you for your time.\n"); 71 | return true; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /03-07-并发阶段任务中的阶段切换/src/com/concurrency/task/Student.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.Phaser; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * 学生类 9 | */ 10 | public class Student implements Runnable { 11 | /** 12 | * 控制线程执行的阶段对象 13 | */ 14 | private Phaser phaser; 15 | 16 | /** 17 | * 构造函数 18 | * @param phaser 控制线程招手执行的阶段对象 19 | */ 20 | public Student(Phaser phaser) { 21 | this.phaser = phaser; 22 | } 23 | 24 | /** 25 | * 核心方法,进入考试状态,做三个测试题,每做完一个测试题,它调用阶段对象等待所有其的学生都完成同样的测试题 26 | */ 27 | @Override 28 | public void run() { 29 | System.out.printf("%s: Has arrived to do the exam. %s\n", Thread.currentThread().getName(), new Date()); 30 | phaser.arriveAndAwaitAdvance(); 31 | 32 | System.out.printf("%s: Is going to do the first exercise. %s\n", Thread.currentThread().getName(), new Date()); 33 | doExercise1(); 34 | System.out.printf("%s: Has done the first exercise. %s\n", Thread.currentThread().getName(), new Date()); 35 | phaser.arriveAndAwaitAdvance(); 36 | 37 | System.out.printf("%s: Is going to do the second exercise. %s\n", Thread.currentThread().getName(), new Date()); 38 | doExercise2(); 39 | System.out.printf("%s: Has done the second exercise. %s\n", Thread.currentThread().getName(), new Date()); 40 | phaser.arriveAndAwaitAdvance(); 41 | 42 | System.out.printf("%s: Is going to do the third exercise. %s\n", Thread.currentThread().getName(), new Date()); 43 | doExercise3(); 44 | System.out.printf("%s: Has finished the exam. %s\n", Thread.currentThread().getName(), new Date()); 45 | phaser.arriveAndAwaitAdvance(); 46 | } 47 | 48 | /** 49 | * 做一个测试题,并且休眠[0, 10)秒 50 | */ 51 | private void doExercise1() { 52 | try { 53 | Long duration = (long) (Math.random() * 10); 54 | TimeUnit.SECONDS.sleep(duration); 55 | } catch (InterruptedException e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | 60 | /** 61 | * 做一个测试题,并且休眠[0, 10)秒 62 | */ 63 | private void doExercise2() { 64 | try { 65 | Long duration = (long) (Math.random() * 10); 66 | TimeUnit.SECONDS.sleep(duration); 67 | } catch (InterruptedException e) { 68 | e.printStackTrace(); 69 | } 70 | } 71 | 72 | /** 73 | * 做一个测试题,并且休眠[0, 10)秒 74 | */ 75 | private void doExercise3() { 76 | try { 77 | Long duration = (long) (Math.random() * 10); 78 | TimeUnit.SECONDS.sleep(duration); 79 | } catch (InterruptedException e) { 80 | e.printStackTrace(); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /03-08-并发任务间的数据交换/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Consumer; 4 | import com.concurrency.task.Producer; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.concurrent.Exchanger; 9 | 10 | public class Main { 11 | public static void main(String[] args) { 12 | // 创建两个缓存对象 13 | List buffer1 = new ArrayList<>(); 14 | List buffer2 = new ArrayList<>(); 15 | 16 | // 创建一个交换器对象 17 | Exchanger> exchanger = new Exchanger<>(); 18 | 19 | // 创建生产者对象 20 | Producer producer = new Producer(exchanger, buffer1); 21 | // 创建消费者对象 22 | Consumer consumer = new Consumer(exchanger, buffer2); 23 | 24 | // 创建消费者对象和生产者对象放置在不同的线程中 25 | Thread threadProducer = new Thread(producer); 26 | Thread threadConsumer = new Thread(consumer); 27 | 28 | // 启动两个线程 29 | threadProducer.start(); 30 | threadConsumer.start(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /03-08-并发任务间的数据交换/src/com/concurrency/task/Consumer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.List; 4 | import java.util.concurrent.Exchanger; 5 | 6 | /** 7 | * 消费者类 8 | */ 9 | public class Consumer implements Runnable { 10 | 11 | /** 12 | * 消费者消费数据的地方,也是与消费者交换数据的地方 13 | */ 14 | private List buffer; 15 | /** 16 | * 同步生产者与消息者交换数据的交换对象 17 | */ 18 | private final Exchanger> exchanger; 19 | 20 | /** 21 | * 构造函数,初始化属性 22 | * 23 | * @param exchanger 数据的交换对象 24 | * @param buffer 数据存储对象 25 | */ 26 | public Consumer(Exchanger> exchanger, List buffer) { 27 | this.exchanger = exchanger; 28 | this.buffer = buffer; 29 | } 30 | 31 | /** 32 | * 核心方法,它消费生产者产生的事件,每消费10个事件后,它使用交换对象去同步生产者。 33 | * 它将已经消费完的空缓存对象发送给生产者,同时获取生产者生产的装有10个事件的缓存对象 34 | */ 35 | @Override 36 | public void run() { 37 | int cycle = 1; 38 | for (int i = 0; i < 10; i++) { 39 | System.out.printf("Consumer: Cycle %d\n", cycle); 40 | 41 | try { 42 | // 等待生产的数据,并且将空的缓存对象发送给生产者 43 | buffer = exchanger.exchange(buffer); 44 | } catch (InterruptedException e) { 45 | e.printStackTrace(); 46 | } 47 | 48 | System.out.printf("Consumer: %d\n", buffer.size()); 49 | 50 | for (int j = 0; j < 10; j++) { 51 | String message = buffer.get(0); 52 | System.out.printf("Consumer: %s\n", message); 53 | buffer.remove(0); 54 | } 55 | 56 | cycle++; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /03-08-并发任务间的数据交换/src/com/concurrency/task/Producer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.List; 4 | import java.util.concurrent.Exchanger; 5 | 6 | /** 7 | * 生产者类 8 | */ 9 | public class Producer implements Runnable { 10 | /** 11 | * 生产者生产数据后存储的地方,也是与消费者交换数据的地方 12 | */ 13 | private List buffer; 14 | /** 15 | * 同步生产者与消息者交换数据的交换对象 16 | */ 17 | private final Exchanger> exchanger; 18 | 19 | /** 20 | * 构造函数,初始化属性 21 | * 22 | * @param exchanger 数据的交换对象 23 | * @param buffer 数据存储对象 24 | */ 25 | public Producer(Exchanger> exchanger, List buffer) { 26 | this.exchanger = exchanger; 27 | this.buffer = buffer; 28 | } 29 | 30 | /** 31 | * 核心方法,产生100个事件,分10次产生,每次产生10个事件,每个产生10个事件后, 32 | * 调用数据交换对象去同步消费者。生产者将存放10个事件的缓存对象发送给消费者, 33 | * 并且从消费者那里接收到一个空的缓存对象 34 | */ 35 | @Override 36 | public void run() { 37 | int cycle = 1; 38 | for (int i = 0; i < 10; i++) { 39 | System.out.printf("Producer: Cycle %d\n", cycle); 40 | // 生产10个事件 41 | for (int j = 0; j < 10; j++) { 42 | String message = "Event " + ((i * 10) + j); 43 | System.out.printf("Producer: %s\n", message); 44 | buffer.add(message); 45 | } 46 | 47 | try { 48 | // 与消费者交换数据 49 | buffer = exchanger.exchange(buffer); 50 | } catch (InterruptedException e) { 51 | e.printStackTrace(); 52 | } 53 | 54 | System.out.printf("Producer: %d\n", buffer.size()); 55 | 56 | cycle++; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /04-02-创建线程执行器/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Server; 4 | import com.concurrency.task.Task; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | Server server = new Server(); 9 | 10 | // 发送100个任务到服务器对象,并且完成任务 11 | for (int i = 0; i < 100; i++) { 12 | Task task = new Task("Task " + i); 13 | server.executeTask(task); 14 | } 15 | 16 | server.endServer(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /04-02-创建线程执行器/src/com/concurrency/task/Server.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Executors; 4 | import java.util.concurrent.ThreadPoolExecutor; 5 | 6 | /** 7 | * 服务类,模拟一个服务器 8 | */ 9 | public class Server { 10 | /** 11 | * 线程池执行器,管理请求线程的执行 12 | */ 13 | private ThreadPoolExecutor executor; 14 | 15 | /** 16 | * 构造函数,创建线程执行器对象 17 | */ 18 | public Server() { 19 | executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); // 本质是一个缓冲线程池对象 20 | } 21 | 22 | /** 23 | * 任务执行方法 接收Task对象作为参数并将其提交到执行者 24 | * 25 | * @param task Task对象 26 | */ 27 | public void executeTask(Task task) { 28 | // 首先,写入一条信息到控制台,表明有一个新的任务到达。 29 | System.out.printf("Server: A new task has arrived\n"); 30 | // 然后,调用执行者的execute()方法来提交这个任务 31 | executor.execute(task); 32 | // 最后,将执行者的数据写入到控制台来看它们的状态 33 | System.out.printf("Server: Pool Size: %d\n", executor.getPoolSize()); 34 | System.out.printf("Server: Active Count: %d\n", executor.getActiveCount()); 35 | System.out.printf("Server: Completed Tasks: %d\n", executor.getCompletedTaskCount()); 36 | } 37 | 38 | /** 39 | * 结束执行的方法 40 | */ 41 | public void endServer() { 42 | // 调用执行者的shutdown()方法来结束任务执行 43 | executor.shutdown(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /04-02-创建线程执行器/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 任务类 8 | */ 9 | public class Task implements Runnable { 10 | /** 11 | * 任务创建的时间 12 | */ 13 | private Date initDate; 14 | /** 15 | * 任务的名称 16 | */ 17 | private String name; 18 | 19 | /** 20 | * 构造函数,初始化属性 21 | * 22 | * @param name 任务的名称 23 | */ 24 | public Task(String name) { 25 | this.initDate = new Date(); 26 | this.name = name; 27 | } 28 | 29 | /** 30 | * 核心类,执行任务,等待一个随机的时间完成任务 31 | */ 32 | @Override 33 | public void run() { 34 | System.out.printf("%s: Task %s: Created on: %s\n", Thread.currentThread().getName(), name, initDate); 35 | System.out.printf("%s: Task %s: Started on: %s\n", Thread.currentThread().getName(), name, new Date()); 36 | 37 | try { 38 | Long duration = (long) (Math.random() * 10); 39 | System.out.printf("%s: Task %s: Doing a task during %d seconds\n", Thread.currentThread().getName(), name, duration); 40 | TimeUnit.SECONDS.sleep(duration); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | } 44 | 45 | System.out.printf("%s: Task %s: Finished on: %s\n", Thread.currentThread().getName(), name, new Date()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /04-03-创建固定大小的线程执行器/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Server; 4 | import com.concurrency.task.Task; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | Server server = new Server(); 9 | 10 | // 发送100个任务到服务器对象,并且完成任务 11 | for (int i = 0; i < 100; i++) { 12 | Task task = new Task("Task " + i); 13 | server.executeTask(task); 14 | } 15 | 16 | server.endServer(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /04-03-创建固定大小的线程执行器/src/com/concurrency/task/Server.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Executors; 4 | import java.util.concurrent.ThreadPoolExecutor; 5 | 6 | /** 7 | * 服务类,模拟一个服务器 8 | */ 9 | public class Server { 10 | /** 11 | * 线程池执行器,管理请求线程的执行 12 | */ 13 | private ThreadPoolExecutor executor; 14 | 15 | /** 16 | * 构造函数,创建线程执行器对象 17 | */ 18 | public Server() { 19 | executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5); // 本质是一个固定大小的线程池对象 20 | } 21 | 22 | /** 23 | * 任务执行方法 接收Task对象作为参数并将其提交到执行者 24 | * 25 | * @param task Task对象 26 | */ 27 | public void executeTask(Task task) { 28 | // 首先,写入一条信息到控制台,表明有一个新的任务到达。 29 | System.out.printf("Server: A new task has arrived\n"); 30 | // 然后,调用执行者的execute()方法来提交这个任务 31 | executor.execute(task); 32 | // 最后,将执行者的数据写入到控制台来看它们的状态 33 | System.out.printf("Server: Pool Size: %d\n", executor.getPoolSize()); 34 | System.out.printf("Server: Active Count: %d\n", executor.getActiveCount()); 35 | System.out.printf("Server: Task Count: %d\n",executor.getTaskCount()); 36 | System.out.printf("Server: Completed Tasks: %d\n",executor.getCompletedTaskCount()); 37 | } 38 | 39 | /** 40 | * 结束执行的方法 41 | */ 42 | public void endServer() { 43 | // 调用执行者的shutdown()方法来结束任务执行 44 | executor.shutdown(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /04-03-创建固定大小的线程执行器/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 任务类 8 | */ 9 | public class Task implements Runnable { 10 | /** 11 | * 任务创建的时间 12 | */ 13 | private Date initDate; 14 | /** 15 | * 任务的名称 16 | */ 17 | private String name; 18 | 19 | /** 20 | * 构造函数,初始化属性 21 | * 22 | * @param name 任务的名称 23 | */ 24 | public Task(String name) { 25 | this.initDate = new Date(); 26 | this.name = name; 27 | } 28 | 29 | /** 30 | * 核心类,执行任务,等待一个随机的时间完成任务 31 | */ 32 | @Override 33 | public void run() { 34 | System.out.printf("%s: Task %s: Created on: %s\n", Thread.currentThread().getName(), name, initDate); 35 | System.out.printf("%s: Task %s: Started on: %s\n", Thread.currentThread().getName(), name, new Date()); 36 | 37 | try { 38 | Long duration = (long) (Math.random() * 10); 39 | System.out.printf("%s: Task %s: Doing a task during %d seconds\n", Thread.currentThread().getName(), name, duration); 40 | TimeUnit.SECONDS.sleep(duration); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | } 44 | 45 | System.out.printf("%s: Task %s: Finished on: %s\n", Thread.currentThread().getName(), name, new Date()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /04-04-在执行器中执行任务并返回结果/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.FactorialCalculator; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Random; 8 | import java.util.concurrent.ExecutionException; 9 | import java.util.concurrent.Executors; 10 | import java.util.concurrent.Future; 11 | import java.util.concurrent.ThreadPoolExecutor; 12 | 13 | public class Main { 14 | public static void main(String[] args) { 15 | // 创建固定大小的线程池执行器,最多可以同时执行2个线程。 16 | ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2); 17 | // 创建一个存储未来象的列表,未来对象关联着任务的任务的执行,并且可以获取执行的结果 18 | List> resultList = new ArrayList<>(); 19 | // 创建一个随机数生成对象 20 | Random random = new Random(); 21 | 22 | // 创建10个任务并且将它们送到执行器中 23 | for (int i = 0; i < 10; i++) { 24 | // 生成[0, 10)之间的10个随机数 25 | Integer number = random.nextInt(10); 26 | FactorialCalculator calculator = new FactorialCalculator(number); 27 | // 调用执行器的submit()方法来提交FactorialCalculator任务给执行者。 28 | // 这个方法返回Future对象来管理任务,并且最终获取它的结果。 29 | Future result = executor.submit(calculator); 30 | // 将结果存储到队列当中 31 | resultList.add(result); 32 | } 33 | // 创建一个do循环来监控执行者的状态,等待10个线程都完成任务。 34 | do { 35 | // 首先,写入信息到控制台,使用执行器的getCompletedTaskNumber()方法获得的已完成的任务数。 36 | System.out.printf("Main: Number of Completed Tasks: %d\n", executor.getCompletedTaskCount()); 37 | // 然后,对于队列中的10个Future对象,使用isDone()方法,将信息写入(到控制台)表明它们所管理的任务是否已经完成 38 | for (int i = 0; i < resultList.size(); i++) { 39 | Future result = resultList.get(i); 40 | System.out.printf("Main: Task %d: %s\n", i, result.isDone()); 41 | } 42 | 43 | try { 44 | // 主线程休眠50毫秒 45 | Thread.sleep(50); 46 | } catch (InterruptedException e) { 47 | e.printStackTrace(); 48 | } 49 | // 如果执行器中的已完成任务数小于10,重复这个循环。 50 | } while (executor.getCompletedTaskCount() < resultList.size()); 51 | 52 | // 将获得的每个任务的结果写入控制台。对于每个Future对象,通过它的任务使用get()方法获取返回的Integer对象。 53 | System.out.printf("Main: Results\n"); 54 | for (int i = 0; i < resultList.size(); i++) { 55 | Future result = resultList.get(i); 56 | Integer number = null; 57 | try { 58 | number = result.get(); 59 | } catch (InterruptedException e) { 60 | e.printStackTrace(); 61 | } catch (ExecutionException e) { 62 | e.printStackTrace(); 63 | } 64 | // 在控制台输出结果 65 | System.out.printf("Core: Task %d: %d\n", i, number); 66 | } 67 | 68 | // 最后,调用执行器的shutdown()方法来结束这个执行器。 69 | executor.shutdown(); 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /04-04-在执行器中执行任务并返回结果/src/com/concurrency/task/FactorialCalculator.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Callable; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 阶乘计算类,实现Callable接口,并参数化为Integer类型 8 | */ 9 | public class FactorialCalculator implements Callable { 10 | /** 11 | * 声明一个私有的,类型为Integer,名为number的属性,用来存储任务将要计算的数 12 | */ 13 | private Integer number; 14 | 15 | /** 16 | * 构造函数,初始化 17 | * @param number 将要计算的数 18 | */ 19 | public FactorialCalculator(Integer number) { 20 | this.number = number; 21 | } 22 | 23 | /** 24 | * 核心方法,返回阶乘计算的结果 25 | * @return 阶乘计算的结果 26 | * @throws Exception 27 | */ 28 | @Override 29 | public Integer call() throws Exception { 30 | int num, result; 31 | num = number; 32 | result = 1; 33 | 34 | // 如果数是1或0,则返回1。否则,计算这个数的阶乘。为了演示效果,在两次乘之间,令这个任务睡眠20毫秒。 35 | if (num == 0 || num == 1) { 36 | return 1; 37 | } else { 38 | for (int i = 2; i <= number; i++) { 39 | result *= i; 40 | TimeUnit.MICROSECONDS.sleep(20); 41 | } 42 | 43 | } 44 | // 操作结果的信息写入控制台。 45 | System.out.printf("%s: %d\n", Thread.currentThread().getName(), result); 46 | // 返回操作结果。 47 | return result; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /04-05-运行多个任务并处理第一个结果/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.TaskValidator; 4 | import com.concurrency.task.UserValidator; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.concurrent.ExecutionException; 9 | import java.util.concurrent.ExecutorService; 10 | import java.util.concurrent.Executors; 11 | 12 | public class Main { 13 | public static void main(String[] args) { 14 | // 创建两个String对象,一个名为name,另一个名为password,使用”test”值初始化它们。 15 | String username = "test"; 16 | String password = "test"; 17 | 18 | // 创建两个UserValidator对象,一个名为ldapValidator,另一个名为dbValidator。 19 | UserValidator ldapValidator = new UserValidator("LDAP"); 20 | UserValidator dbValidator = new UserValidator("DataBase"); 21 | 22 | // 创建两个TaskValidator对象,分别为ldapTask和dbTask。分别使用ldapValidator和dbValidator初始化它们。 23 | TaskValidator ldapTask = new TaskValidator(ldapValidator, username, password); 24 | TaskValidator dbTask = new TaskValidator(dbValidator, username, password); 25 | 26 | // 创建TaskValidator队列,添加两个已创建的对象(ldapTask和dbTask) 27 | List taskList = new ArrayList<>(); 28 | taskList.add(ldapTask); 29 | taskList.add(dbTask); 30 | 31 | // 使用Executors类的newCachedThreadPool()方法创建一个新的ThreadPoolExecutor对象和一个类型为String, 32 | // 名为result的变量。 33 | ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool(); 34 | String result; 35 | try { 36 | // 调用executor对象的invokeAny()方法。该方法接收taskList参数,返回String类型。 37 | // 同样,它将该方法返回的String对象写入到控制台。 38 | result = executor.invokeAny(taskList); 39 | System.out.printf("Main: Result: %s\n", result); 40 | } catch (InterruptedException e) { 41 | e.printStackTrace(); 42 | } catch (ExecutionException e) { 43 | e.printStackTrace(); 44 | } 45 | 46 | // 使用shutdown()方法结束执行者,写入一条信息到控制台,表明程序已结束。 47 | executor.shutdown(); 48 | System.out.printf("Main: End of the Execution\n"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /04-05-运行多个任务并处理第一个结果/src/com/concurrency/task/TaskValidator.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Callable; 4 | 5 | /** 6 | * 任务验证类,用来执行UserValidation对象作为并发任务的验证过程。指定它实现Callable接口,并参数化为String类型。 7 | */ 8 | public class TaskValidator implements Callable { 9 | /** 10 | * 声明一个私有的、类型为UserValidator、名为validator的属性。 11 | */ 12 | private UserValidator validator; 13 | /** 14 | * 声明私有的、类型为String、名为user的属性。 15 | */ 16 | private String user; 17 | /** 18 | * 声明私有的、类型为String、名为password的属性。 19 | */ 20 | private String password; 21 | 22 | /** 23 | * 构造函数,初始化属性 24 | * 25 | * @param validator 用户验证对象 26 | * @param user 用户名 27 | * @param password 用户密码 28 | */ 29 | public TaskValidator(UserValidator validator, String user, String password) { 30 | this.validator = validator; 31 | this.user = user; 32 | this.password = password; 33 | } 34 | 35 | /** 36 | * 核心方法,使用用户验证对象进行用户名和密码验证,如果验证通过就返回验证的名字,否则就抛出异常 37 | * 38 | * @return 验证的名字 39 | * @throws Exception 验证不通过就抛出异常 40 | */ 41 | @Override 42 | public String call() throws Exception { 43 | // 如果用户没有通过UserValidator对象验证,写入一条信息到控制台,表明这种情况,并且抛出一个Exception异常 44 | if (!validator.validate(user, password)) { 45 | System.out.printf("%s: The user has not been found\n", validator.getName()); 46 | throw new Exception("Error validating user"); 47 | } 48 | 49 | // 否则,写入一条信息到控制台表明用户已通过验证,并返回UserValidator对象的名称。 50 | System.out.printf("%s: The user has been found\n", validator.getName()); 51 | return validator.getName(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /04-05-运行多个任务并处理第一个结果/src/com/concurrency/task/UserValidator.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 用户检验类,实现用户验证过程 8 | */ 9 | public class UserValidator { 10 | /** 11 | * 声明一个私有的、类型为String、名为name的属性,用来存储系统验证用户的名称。 12 | */ 13 | private String name; 14 | 15 | /** 16 | * 构造函数,初始化用户名称 17 | * 18 | * @param name 用户名称 19 | */ 20 | public UserValidator(String name) { 21 | this.name = name; 22 | } 23 | 24 | /** 25 | * 验证方法,根据用户名和密码进行验 26 | * 27 | * @param name 用户名 28 | * @param password 密码 29 | * @return true验证通过,false验证失败 30 | */ 31 | public boolean validate(String name, String password) { 32 | // 创建Random对象,名为random。 33 | Random random = new Random(); 34 | 35 | // 等待一个随机时间,用来模拟用户验证的过程 36 | try { 37 | Long duration = (long) (Math.random() * 10); 38 | System.out.printf("Validator %s: Validating a user during %d seconds\n", this.name, duration); 39 | TimeUnit.SECONDS.sleep(duration); 40 | } catch (InterruptedException e) { 41 | return false; 42 | } 43 | 44 | // 返回一个随机Boolean值。如果用户验证通过,这个方法将返回true,否则,返回false。 45 | return random.nextBoolean(); 46 | } 47 | 48 | /** 49 | * 返回name属性值 50 | * 51 | * @return name属性值 52 | */ 53 | public String getName() { 54 | return name; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /04-06-运行多个任务并且处理所有结果/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Result; 4 | import com.concurrency.task.Task; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.concurrent.*; 9 | 10 | public class Main { 11 | public static void main(String[] args) { 12 | // 使用Executors类的newCachedThreadPool()方法,创建ThreadPoolExecutor对象。 13 | ExecutorService executor = Executors.newCachedThreadPool(); 14 | 15 | // 创建三个Task对象,并且将他们存储在一个链表当中 16 | List taskList = new ArrayList<>(); 17 | for (int i = 0; i < 3; i++) { 18 | Task task = new Task("Task-" + i); 19 | taskList.add(task); 20 | } 21 | 22 | // 创建Future对象列表,参数化为Result类型。 23 | List> resultList = null; 24 | try { 25 | // 调用ThreadPoolExecutor类的invokeAll()方法。这个类将会返回之前创建的Future对象列表。 26 | resultList = executor.invokeAll(taskList); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | 31 | // 使用shutdown()方法结束执行器的执行。 32 | executor.shutdown(); 33 | 34 | // 将结果写入控制台 35 | System.out.printf("Core: Printing the results\n"); 36 | for (Future future : resultList) { 37 | try { 38 | Result result = future.get(); 39 | System.out.printf("%s: %s\n", result.getName(), result.getValue()); 40 | } catch (InterruptedException | ExecutionException e) { 41 | e.printStackTrace(); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /04-06-运行多个任务并且处理所有结果/src/com/concurrency/task/Result.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 结果类,存储中并发任务产生的结果 5 | */ 6 | public class Result { 7 | /** 8 | * 产生结果的任务的名字 9 | */ 10 | private String name; 11 | /** 12 | * 产生的结果值 13 | */ 14 | private int value; 15 | 16 | /** 17 | * 返回任务的名字 18 | * 19 | * @return 任务的名字 20 | */ 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | /** 26 | * 设备任务的名字 27 | * 28 | * @param name 任务的名字 29 | */ 30 | public void setName(String name) { 31 | this.name = name; 32 | } 33 | 34 | /** 35 | * 返回结果 36 | * 37 | * @return 结果值 38 | */ 39 | public int getValue() { 40 | return value; 41 | } 42 | 43 | /** 44 | * 设置结果 45 | * 46 | * @param value 结果值 47 | */ 48 | public void setValue(int value) { 49 | this.value = value; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /04-06-运行多个任务并且处理所有结果/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Callable; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 任务类,实现Callable接口,参数化为Result类型。 8 | */ 9 | public class Task implements Callable { 10 | /** 11 | * 任务的名称 12 | */ 13 | private String name; 14 | 15 | /** 16 | * 构造函数 17 | * 18 | * @param name 初始化任务的名称 19 | */ 20 | public Task(String name) { 21 | this.name = name; 22 | } 23 | 24 | /** 25 | * 核心方法,等待一个随机时间,并且计算5个随机数的和 26 | * 27 | * @return 个随机数的和 28 | * @throws Exception 29 | */ 30 | @Override 31 | public Result call() throws Exception { 32 | // 向控制台输出信息 33 | System.out.printf("%s: Staring\n", this.name); 34 | 35 | // 等待一个随机的时间 36 | try { 37 | Long duration = (long) (Math.random() * 10); 38 | System.out.printf("%s: Waiting %d seconds for results.\n", this.name, duration); 39 | TimeUnit.SECONDS.sleep(duration); 40 | } catch (InterruptedException e) { 41 | e.printStackTrace(); 42 | } 43 | 44 | // 计算随机数的和 45 | int value = 0; 46 | for (int i = 0; i < 5; i++) { 47 | value += (int) (Math.random() * 100); 48 | 49 | } 50 | 51 | // 创建一个结果对象 52 | Result result = new Result(); 53 | result.setName(this.name); 54 | result.setValue(value); 55 | System.out.printf("%s: Ends\n", this.name); 56 | 57 | // 返回结果对象 58 | return result; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /04-07-在执行器中延时执行任务/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Task; 4 | 5 | import java.util.Date; 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.ScheduledExecutorService; 8 | import java.util.concurrent.ScheduledThreadPoolExecutor; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | public class Main { 12 | public static void main(String[] args) { 13 | // 创建一个定时线程池执行器对象 14 | ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1); 15 | 16 | // 使用ScheduledThreadPoolExecutor实例的schedule()方法,初始化和开始一些任务(5个任务)。 17 | System.out.printf("Main: Starting at: %s\n", new Date()); 18 | for (int i = 0; i < 5; i++) { 19 | Task task = new Task("Task " + i); 20 | executor.schedule(task, i + 1, TimeUnit.SECONDS); 21 | } 22 | 23 | // 关闭线程执行器对象 24 | executor.shutdown(); 25 | 26 | // 等待线程执行器的完成 27 | try { 28 | // 所有线程必须在24小时内完成,否则就终止未完成的线程 29 | executor.awaitTermination(1, TimeUnit.DAYS); 30 | } catch (InterruptedException e) { 31 | e.printStackTrace(); 32 | } 33 | 34 | // 输出完成消息 35 | System.out.printf("Core: Ends at: %s\n", new Date()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /04-07-在执行器中延时执行任务/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.Callable; 5 | 6 | /** 7 | * 任务类,实现Callable接口,参数化为String类型。 8 | */ 9 | public class Task implements Callable { 10 | /** 11 | * 任务名称 12 | */ 13 | private String name; 14 | 15 | /** 16 | * 构造函数,初始化任务名称 17 | * 18 | * @param name 任务名称 19 | */ 20 | public Task(String name) { 21 | this.name = name; 22 | } 23 | 24 | /** 25 | * 核心方法,输出任务执行时间 26 | * 27 | * @return 执行结果字符串 28 | * @throws Exception 29 | */ 30 | @Override 31 | public String call() throws Exception { 32 | System.out.printf("%s: Starting at : %s\n", name, new Date()); 33 | return "Hello, world"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /04-08-在执行器中周期性执行任务/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Task; 4 | 5 | import java.util.Date; 6 | import java.util.concurrent.*; 7 | 8 | public class Main { 9 | public static void main(String[] args) { 10 | // 创建一个定时行器服务对象 11 | ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 12 | System.out.printf("Main: Starting at: %s\n", new Date()); 13 | 14 | // 创建一个执行任务,并且将它放入执行器中,初始延迟是1秒,周期是2秒 15 | Task task = new Task("Task"); 16 | ScheduledFuture result = executor.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS); 17 | 18 | // 控制任务的执行 19 | for (int i = 0; i < 10; i++) { 20 | System.out.printf("Main: Delay: %d\n", result.getDelay(TimeUnit.MILLISECONDS)); 21 | try { 22 | TimeUnit.MILLISECONDS.sleep(500); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | 28 | // 关闭执行器对象 29 | executor.shutdown(); 30 | System.out.printf("Main: No more tasks at: %s\n", new Date()); 31 | 32 | // 验证在执行器关闭后,周期性任务不会执行 33 | try { 34 | TimeUnit.SECONDS.sleep(5); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | // 输出完成信息 39 | System.out.printf("Main: Finished at: %s\n", new Date()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /04-08-在执行器中周期性执行任务/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * 任务类,执行任务 7 | */ 8 | public class Task implements Runnable { 9 | /** 10 | * 任务的名称 11 | */ 12 | private String name; 13 | 14 | /** 15 | * 构造函数,初始化任务名称 16 | * 17 | * @param name 任务名称 18 | */ 19 | public Task(String name) { 20 | this.name = name; 21 | } 22 | 23 | /** 24 | * 核心方法,向控制台输出当前执行的时间 25 | */ 26 | @Override 27 | public void run() { 28 | System.out.printf("%s: Executed at: %s\n",name,new Date()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /04-09-在执行器中取消任务/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Task; 4 | 5 | import java.util.concurrent.Executors; 6 | import java.util.concurrent.Future; 7 | import java.util.concurrent.ThreadPoolExecutor; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class Main { 11 | public static void main(String[] args) { 12 | // 创建一个执行器 13 | ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); 14 | 15 | // 创建一个任务 16 | Task task = new Task(); 17 | 18 | System.out.printf("Main: Executing the Task\n"); 19 | 20 | // 把任务发送到执行器 21 | Future result = executor.submit(task); 22 | 23 | // 休眠两秒钟 24 | try { 25 | TimeUnit.SECONDS.sleep(2); 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } 29 | 30 | // 取消一个任务完成他的执行 31 | System.out.printf("Main: Cancelling the Task\n"); 32 | result.cancel(true); 33 | 34 | // 验证任务是否被取消 35 | System.out.printf("Main: Cancelled: %s\n", result.isCancelled()); 36 | System.out.printf("Main: Done: %s\n", result.isDone()); 37 | 38 | // 关闭执行器 39 | executor.shutdown(); 40 | System.out.printf("Main: The executor has finished\n"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /04-09-在执行器中取消任务/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Callable; 4 | 5 | public class Task implements Callable { 6 | /** 7 | * 核心方法,一个无限循环的任务,每100毫秒向控制台写一个消息 8 | * @return 9 | * @throws Exception 10 | */ 11 | @Override 12 | public String call() throws Exception { 13 | while (true){ 14 | System.out.printf("Task: Test\n"); 15 | Thread.sleep(100); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /04-10-在执行器中控制任务的完成/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.ExecutableTask; 4 | import com.concurrency.task.ResultTask; 5 | 6 | import java.util.concurrent.ExecutionException; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Executors; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | public class Main { 12 | public static void main(String[] args) { 13 | // 创建一个执行器对象 14 | ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool(); 15 | 16 | // 创建5个任务 17 | ResultTask resultTasks[] = new ResultTask[5]; 18 | for (int i = 0; i < 5; i++) { 19 | ExecutableTask executableTask = new ExecutableTask("Task " + i); 20 | resultTasks[i] = new ResultTask(executableTask); 21 | executor.submit(resultTasks[i]); 22 | } 23 | 24 | // 休眠5秒钟 25 | try { 26 | TimeUnit.SECONDS.sleep(5); 27 | } catch (InterruptedException e1) { 28 | e1.printStackTrace(); 29 | } 30 | 31 | // 取消所有的任务,如果任务在取消之前已经完,取消操作对任务没有任命影响 32 | for (ResultTask resultTask : resultTasks) { 33 | resultTask.cancel(true); 34 | } 35 | 36 | // 输出未被取消的任务的结果 37 | for (ResultTask resultTask : resultTasks) { 38 | try { 39 | if (!resultTask.isCancelled()) { 40 | System.out.printf("%s\n", resultTask.get()); 41 | } 42 | } catch (InterruptedException | ExecutionException e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | 47 | // 关闭执行器 48 | executor.shutdown(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /04-10-在执行器中控制任务的完成/src/com/concurrency/task/ExecutableTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Callable; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 任务执行类,并指定其实现Callable接口,参数化为String类型。 8 | */ 9 | public class ExecutableTask implements Callable { 10 | /** 11 | * 任务名称 12 | */ 13 | private String name; 14 | 15 | public ExecutableTask(String name) { 16 | this.name = name; 17 | } 18 | 19 | /** 20 | * 核心方法,等待一个随机时间,返回一个结果 21 | * 22 | * @return 字符串结果 23 | * @throws Exception 24 | */ 25 | @Override 26 | public String call() throws Exception { 27 | try { 28 | Long duration = (long) (Math.random() * 10); 29 | System.out.printf("%s: Waiting %d seconds for results.\n", this.name, duration); 30 | TimeUnit.SECONDS.sleep(duration); 31 | } catch (InterruptedException e) { 32 | //e.printStackTrace(); 33 | } 34 | return "Hello, world. I'm " + name; 35 | } 36 | 37 | /** 38 | * 获取任务名称 39 | * 40 | * @return 任务名称 41 | */ 42 | public String getName() { 43 | return name; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /04-10-在执行器中控制任务的完成/src/com/concurrency/task/ResultTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Callable; 4 | import java.util.concurrent.FutureTask; 5 | 6 | /** 7 | * 结果任务类,这个类管理着可执行任务类的执行 8 | */ 9 | public class ResultTask extends FutureTask { 10 | /** 11 | * 结果任务的名称 12 | */ 13 | private String name; 14 | 15 | /** 16 | * 构造函数 17 | * 18 | * @param callable 可调用的接口对象 19 | */ 20 | public ResultTask(Callable callable) { 21 | super(callable); 22 | this.name = ((ExecutableTask) callable).getName(); 23 | } 24 | 25 | /** 26 | * 当任务完成时调用这个方法 27 | */ 28 | @Override 29 | protected void done() { 30 | if (isCancelled()) { 31 | System.out.printf("%s: Has been cancelled\n", name); 32 | } else { 33 | System.out.printf("%s: Has finished\n", name); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.ReportProcessor; 4 | import com.concurrency.task.ReportRequest; 5 | 6 | import java.util.concurrent.*; 7 | 8 | public class Main { 9 | public static void main(String[] args) { 10 | // 创建一个执行器对象和三个完成服务对象,执行器对象供完成服务对象使用 11 | ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool(); 12 | CompletionService service = new ExecutorCompletionService<>(executor); 13 | 14 | // 创建两报表请求对象和两个线程来执行他们 15 | ReportRequest faceRequest = new ReportRequest("Face", service); 16 | ReportRequest onlineRequest = new ReportRequest("Online", service); 17 | Thread faceThread = new Thread(faceRequest); 18 | Thread onlineThread = new Thread(onlineRequest); 19 | 20 | // 创建一个报表处理对象和一个执行它的线程 21 | ReportProcessor processor = new ReportProcessor(service); 22 | Thread senderThread = new Thread(processor); 23 | 24 | // 启动线程 25 | System.out.printf("Main: Starting the Threads\n"); 26 | faceThread.start(); 27 | onlineThread.start(); 28 | senderThread.start(); 29 | 30 | // 等待报表生成器对象的任务完成 31 | try { 32 | System.out.printf("Main: Waiting for the report generators.\n"); 33 | faceThread.join(); 34 | onlineThread.join(); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | 39 | // 关闭执行器 40 | System.out.printf("Main: Shuting down the executor.\n"); 41 | executor.shutdown(); 42 | try { 43 | executor.awaitTermination(1, TimeUnit.DAYS); 44 | } catch (InterruptedException e) { 45 | e.printStackTrace(); 46 | } 47 | 48 | // 等待报表发送器对象执行结束 49 | processor.setEnd(true); 50 | System.out.printf("Main: Ends\n"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/task/ReportGenerator.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.Callable; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 报告生成类,模拟生成报告。 8 | */ 9 | public class ReportGenerator implements Callable { 10 | /** 11 | * 报告发送者 12 | */ 13 | private String sender; 14 | /** 15 | * 报告的标题 16 | */ 17 | private String title; 18 | 19 | /** 20 | * 构造函数,初始化报告发送者,报告的标题 21 | * 22 | * @param sender 报告发送者 23 | * @param title 报告的标题 24 | */ 25 | public ReportGenerator(String sender, String title) { 26 | this.sender = sender; 27 | this.title = title; 28 | } 29 | 30 | /** 31 | * 核心方法,等待一个随机时间,产生一个字符串类型的报告 32 | * 33 | * @return 字符串类型的报告 34 | * @throws Exception 35 | */ 36 | @Override 37 | public String call() throws Exception { 38 | try { 39 | Long duration = (long) (Math.random() * 10); 40 | System.out.printf("%s_%s: ReportGenerator: Generating a report during %d seconds\n", this.sender, this.title, duration); 41 | TimeUnit.SECONDS.sleep(duration); 42 | } catch (InterruptedException e) { 43 | e.printStackTrace(); 44 | } 45 | String ret = sender + ": " + title; 46 | return ret; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/task/ReportProcessor.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.CompletionService; 4 | import java.util.concurrent.ExecutionException; 5 | import java.util.concurrent.Future; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * 报表处理器类,通过CompletionService对象处理报表生成器的结果 10 | */ 11 | public class ReportProcessor implements Runnable { 12 | /** 13 | * 完成服务对象 14 | */ 15 | private CompletionService service; 16 | /** 17 | * 任务完成的标记 18 | */ 19 | private boolean end; 20 | 21 | /** 22 | * 构造函数,初始化完成服务对象 23 | * 24 | * @param service 完成服务对象 25 | */ 26 | public ReportProcessor(CompletionService service) { 27 | this.service = service; 28 | } 29 | 30 | 31 | /** 32 | * 核心方法,如果任务没有完成就一直执行 33 | */ 34 | @Override 35 | public void run() { 36 | while (!end) { 37 | try { 38 | // 调用CompletionService接口的poll()方法,获取CompletionService执行的下个已完成任务的Future对象 39 | Future result = service.poll(20, TimeUnit.SECONDS); 40 | if (result != null) { 41 | // 使用Future对象的get()方法获取任务的结果,并且将这些结果写入到控制台 42 | String report = result.get(); 43 | System.out.printf("ReportReceiver: Report Received: %s\n", report); 44 | } 45 | } catch (InterruptedException | ExecutionException e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | 50 | System.out.printf("ReportSender: End\n"); 51 | } 52 | 53 | /** 54 | * 设置任务完成标记 55 | * @param end 任务完成标记 56 | */ 57 | public void setEnd(boolean end) { 58 | this.end = end; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /04-11-在执行器中分离任务的启动与结果的处理/src/com/concurrency/task/ReportRequest.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.CompletionService; 4 | 5 | /** 6 | * 报告请求类 7 | */ 8 | public class ReportRequest implements Runnable { 9 | /** 10 | * 报告请求类的名字 11 | */ 12 | private String name; 13 | /** 14 | * 完成任务对象 15 | */ 16 | private CompletionService service; 17 | 18 | /** 19 | * 构造函数,初始化报告请求类的名字,完成任务对象 20 | * 21 | * @param name 报告请求类的名字 22 | * @param service 完成任务对象 23 | */ 24 | public ReportRequest(String name, CompletionService service) { 25 | this.name = name; 26 | this.service = service; 27 | } 28 | 29 | /** 30 | * 核心方法,创建一个报告生成对象,并且将其提交到完成任务对象 31 | */ 32 | @Override 33 | public void run() { 34 | ReportGenerator reportGenerator = new ReportGenerator(name, "Report"); 35 | service.submit(reportGenerator); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /04-12-处理在执行器中被拒绝的任务/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.RejectedTaskController; 4 | import com.concurrency.task.Task; 5 | 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.ThreadPoolExecutor; 8 | 9 | public class Main { 10 | public static void main(String[] args) { 11 | // 创建拒绝任务控制器对象 12 | // Create the controller for the Rejected tasks 13 | RejectedTaskController controller = new RejectedTaskController(); 14 | // 创建执行器对象,并且设置拒绝执行处理器对象 15 | ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); 16 | executor.setRejectedExecutionHandler(controller); 17 | 18 | // 运行三个任务 19 | System.out.printf("Main: Starting.\n"); 20 | for (int i = 0; i < 3; i++) { 21 | Task task = new Task("Task" + i); 22 | executor.submit(task); 23 | } 24 | 25 | // 关闭执行器 26 | System.out.printf("Main: Shuting down the Executor.\n"); 27 | executor.shutdown(); 28 | 29 | // 发送另外一个任务 30 | System.out.printf("Main: Sending another Task.\n"); 31 | Task task = new Task("RejectedTask"); 32 | executor.submit(task); 33 | 34 | // 程序结束 35 | System.out.printf("Main: End.\n"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /04-12-处理在执行器中被拒绝的任务/src/com/concurrency/task/RejectedTaskController.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.RejectedExecutionHandler; 4 | import java.util.concurrent.ThreadPoolExecutor; 5 | 6 | /** 7 | * 拒绝任务处理器类 8 | */ 9 | public class RejectedTaskController implements RejectedExecutionHandler { 10 | /** 11 | * 核心方法,在控制台输出已被拒绝的任务的名称和 执行器的状态。 12 | * @param r 13 | * @param executor 14 | */ 15 | @Override 16 | public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { 17 | System.out.printf("RejectedTaskController: The task %s has been rejected\n", r.toString()); 18 | System.out.printf("RejectedTaskController: %s\n", executor.toString()); 19 | System.out.printf("RejectedTaskController: Terminating: %s\n", executor.isTerminating()); 20 | System.out.printf("RejectedTasksController: Terminated: %s\n", executor.isTerminated()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /04-12-处理在执行器中被拒绝的任务/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | /** 6 | * 任务类,执行一个随机时间的任务 7 | */ 8 | public class Task implements Runnable { 9 | private String name; 10 | 11 | public Task(String name) { 12 | this.name = name; 13 | } 14 | 15 | @Override 16 | public void run() { 17 | System.out.printf("Task %s: Starting\n", name); 18 | try { 19 | Long duration = (long) (Math.random() * 10); 20 | System.out.printf("Task %s: ReportGenerator: Generating a report during %d seconds\n", name, duration); 21 | TimeUnit.SECONDS.sleep(duration); 22 | } catch (InterruptedException e) { 23 | e.printStackTrace(); 24 | } 25 | System.out.printf("Task %s: Ending\n", name); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return name; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /05-02-创建Fork-Join线程池/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Task; 4 | import com.concurrency.utils.Product; 5 | import com.concurrency.utils.ProductListGenerator; 6 | 7 | import java.util.List; 8 | import java.util.concurrent.ForkJoinPool; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | public class Main { 12 | public static void main(String[] args) { 13 | // 创建产品生成器对象,并且门生产10000个产品 14 | ProductListGenerator generator = new ProductListGenerator(); 15 | List products = generator.generate(10000); 16 | 17 | // 创建一个任务对象 18 | Task task = new Task(products, 0, products.size(), 0.2); 19 | 20 | // 创建一个分合池 21 | ForkJoinPool pool = new ForkJoinPool(); 22 | 23 | // 执行任务 24 | pool.execute(task); 25 | 26 | // 输出分合池的信息 27 | do { 28 | System.out.printf("Main: Thread Count: %d\n", pool.getActiveThreadCount()); 29 | System.out.printf("Main: Thread Steal: %d\n", pool.getStealCount()); 30 | System.out.printf("Main: Paralelism: %d\n", pool.getParallelism()); 31 | try { 32 | TimeUnit.MILLISECONDS.sleep(5); 33 | } catch (InterruptedException e) { 34 | e.printStackTrace(); 35 | } 36 | } while (!task.isDone()); 37 | 38 | // 关闭分合池 39 | pool.shutdown(); 40 | 41 | // 检查任务是否正常完成 42 | if (task.isCompletedNormally()) { 43 | System.out.printf("Main: The process has completed normally.\n"); 44 | } 45 | 46 | // 输出价格不是12的产品 47 | for (Product product : products) { 48 | if (product.getPrice() != 12) { 49 | System.out.printf("Product %s: %f\n", product.getName(), product.getPrice()); 50 | } 51 | } 52 | 53 | // 结束程序 54 | System.out.println("Main: End of the program.\n"); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /05-02-创建Fork-Join线程池/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.utils.Product; 4 | 5 | import java.util.List; 6 | import java.util.concurrent.RecursiveAction; 7 | 8 | /** 9 | *任务执行类,如果产品多于10个就让分出子任务进行处理 10 | */ 11 | public class Task extends RecursiveAction { 12 | private static final long serialVersionUID = 6876633274768462482L; 13 | 14 | /** 15 | * 产品集合对象 16 | */ 17 | private List products; 18 | /** 19 | * 处理的第一个产品位置 20 | */ 21 | private int first; 22 | /** 23 | * 处理的最后一个产品位置 24 | */ 25 | private int last; 26 | /** 27 | * 价格增长率 28 | */ 29 | private double increment; 30 | 31 | /** 32 | * 构造函数,初始化属性 33 | * 34 | * @param products 产品集合对象 35 | * @param first 处理的第一个产品位置 36 | * @param last 处理的最后一个产品位置(不包含) 37 | * @param increment 价格增长率 38 | */ 39 | public Task(List products, int first, int last, double increment) { 40 | this.products = products; 41 | this.first = first; 42 | this.last = last; 43 | this.increment = increment; 44 | } 45 | 46 | /** 47 | * 对产品进行计算 48 | */ 49 | @Override 50 | protected void compute() { 51 | if (last - first < 10) { // 处理的产品数少于10个就提价 52 | updatePrices(); 53 | } else { // 否则就让两个子线程去执行 54 | int middle = (first + last) / 2; 55 | System.out.printf("Task: Pending tasks: %s\n", getQueuedTaskCount()); 56 | Task t1 = new Task(products, first, middle + 1, increment); 57 | Task t2 = new Task(products, middle + 1, last, increment); 58 | invokeAll(t1, t2); 59 | } 60 | } 61 | 62 | /** 63 | * 更价格,将指定的范围内的产品提价 64 | */ 65 | private void updatePrices() { 66 | for (int i = first; i < last; i++) { 67 | Product product = products.get(i); 68 | product.setPrice(product.getPrice() * (1 + increment)); // 按increment比率提价 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /05-02-创建Fork-Join线程池/src/com/concurrency/utils/Product.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.utils; 2 | 3 | /** 4 | * 产品类,保存产品的名称和价格 5 | */ 6 | public class Product { 7 | /** 8 | * 名称 9 | */ 10 | private String name; 11 | /** 12 | * 价格 13 | */ 14 | private double price; 15 | 16 | /** 17 | * 获取产品名称 18 | * 19 | * @return 产品名称 20 | */ 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | /** 26 | * 设置产名品名称 27 | * 28 | * @param name 产名名称 29 | */ 30 | public void setName(String name) { 31 | this.name = name; 32 | } 33 | 34 | /** 35 | * 获取产品价格 36 | * 37 | * @return 产品价格 38 | */ 39 | public double getPrice() { 40 | return price; 41 | } 42 | 43 | /** 44 | * 设置产品价格 45 | * 46 | * @param price 产品价格 47 | */ 48 | public void setPrice(double price) { 49 | this.price = price; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /05-02-创建Fork-Join线程池/src/com/concurrency/utils/ProductListGenerator.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 产品生成器类,根据指定的数量创建产品 8 | */ 9 | public class ProductListGenerator { 10 | 11 | /** 12 | * 产品生产类 13 | * 14 | * @param size 产品数量 15 | * @return 产品集合 16 | */ 17 | public List generate(int size) { 18 | List ret = new ArrayList<>(); 19 | for (int i = 0; i < size; i++) { 20 | Product product = new Product(); 21 | product.setName("Product " + i); 22 | product.setPrice(10); 23 | ret.add(product); 24 | } 25 | 26 | return ret; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /05-03-合并任务的结果/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.DocumentTask; 4 | import com.concurrency.utils.DocumentMock; 5 | 6 | import java.util.concurrent.ExecutionException; 7 | import java.util.concurrent.ForkJoinPool; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class Main { 11 | public static void main(String[] args) { 12 | // 创建一个模拟文档,他有100行,每行1000个单词 13 | // Generate a document with 100 lines and 1000 words per line 14 | DocumentMock mock = new DocumentMock(); 15 | String[][] document = mock.generateDocument(100, 1000, "the"); 16 | 17 | // 创建一个文档任务对象,处理整个文档 18 | DocumentTask task = new DocumentTask(document, 0, 100, "the"); 19 | 20 | // 创建一个分合池对象 21 | ForkJoinPool pool = new ForkJoinPool(); 22 | 23 | // 执行文档处理任务 24 | pool.execute(task); 25 | 26 | // 输出分合池对象的统计数据 27 | do { 28 | System.out.printf("******************************************\n"); 29 | System.out.printf("Main: Parallelism: %d\n", pool.getParallelism()); 30 | System.out.printf("Main: Active Threads: %d\n", pool.getActiveThreadCount()); 31 | System.out.printf("Main: Task Count: %d\n", pool.getQueuedTaskCount()); 32 | System.out.printf("Main: Steal Count: %d\n", pool.getStealCount()); 33 | System.out.printf("******************************************\n"); 34 | 35 | try { 36 | TimeUnit.SECONDS.sleep(1); 37 | } catch (InterruptedException e) { 38 | e.printStackTrace(); 39 | } 40 | 41 | } while (!task.isDone()); 42 | 43 | // 关闭分合池 44 | pool.shutdown(); 45 | 46 | // 等待所有的任务完成 47 | try { 48 | pool.awaitTermination(1, TimeUnit.DAYS); 49 | } catch (InterruptedException e) { 50 | e.printStackTrace(); 51 | } 52 | 53 | // 输出任务完成的结果 54 | try { 55 | System.out.printf("Main: The word appears %d in the document", task.get()); 56 | } catch (InterruptedException | ExecutionException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /05-03-合并任务的结果/src/com/concurrency/task/DocumentTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.concurrent.ExecutionException; 6 | import java.util.concurrent.RecursiveTask; 7 | 8 | /** 9 | * 文档处理类,在文档中查找指定的单词 10 | */ 11 | public class DocumentTask extends RecursiveTask { 12 | private static final long serialVersionUID = -1257254196502539272L; 13 | /** 14 | * 等待处理的文档 15 | */ 16 | private String document[][]; 17 | /** 18 | * 文档处理的开始行 19 | */ 20 | private int start; 21 | /** 22 | * 文档处理的结束行 23 | */ 24 | private int end; 25 | 26 | /** 27 | * 要查找的单词 28 | */ 29 | private String word; 30 | 31 | /** 32 | * 构造函数 33 | * 34 | * @param document 等待处理的文档 35 | * @param start 文档处理的开始行 36 | * @param end 文档处理的结束行 37 | * @param word 要查找的单词 38 | */ 39 | public DocumentTask(String document[][], int start, int end, String word) { 40 | this.document = document; 41 | this.start = start; 42 | this.end = end; 43 | this.word = word; 44 | } 45 | 46 | 47 | /** 48 | * 核心方法,统计文档的中指定的单词 49 | * 50 | * @return 指定的单词出现的次数 51 | */ 52 | @Override 53 | protected Integer compute() { 54 | Integer result = null; 55 | if (end - start < 10) { // 少于10行,使用行处理方法 56 | result = processLines(document, start, end, word); 57 | } else { // 否则使用两个线程去处理 58 | int mid = (start + end) / 2; 59 | DocumentTask task1 = new DocumentTask(document, start, mid, word); 60 | DocumentTask task2 = new DocumentTask(document, mid, end, word); 61 | invokeAll(task1, task2); 62 | try { 63 | result = groupResults(task1.get(), task2.get()); 64 | } catch (InterruptedException | ExecutionException e) { 65 | e.printStackTrace(); 66 | } 67 | } 68 | return result; 69 | } 70 | 71 | /** 72 | * 返回number1+number2的和 73 | * 74 | * @param number1 加数l 75 | * @param number2 加数2 76 | * @return 和 77 | */ 78 | private Integer groupResults(Integer number1, Integer number2) { 79 | return number1 + number2; 80 | } 81 | 82 | /** 83 | * 行处理方法 84 | * 85 | * @param document 等待处理的文档 86 | * @param start 文档处理的开始行 87 | * @param end 文档处理的结束行 88 | * @param word 要查找的单词 89 | * @return 指定的单词出现的次数 90 | */ 91 | private Integer processLines(String[][] document, int start, int end, String word) { 92 | List tasks = new ArrayList(); 93 | 94 | // 有多少行就创建多少个行处理任务对象 95 | for (int i = start; i < end; i++) { 96 | LineTask task = new LineTask(document[i], 0, document[i].length, word); 97 | tasks.add(task); 98 | } 99 | invokeAll(tasks); 100 | 101 | // 统计结果 102 | int result = 0; 103 | for (LineTask task : tasks) { 104 | try { 105 | result = result + task.get(); 106 | } catch (InterruptedException | ExecutionException e) { 107 | e.printStackTrace(); 108 | } 109 | } 110 | return result; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /05-03-合并任务的结果/src/com/concurrency/task/LineTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.List; 4 | import java.util.concurrent.ExecutionException; 5 | import java.util.concurrent.RecursiveTask; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * 行处理类,处理指定行数和单词 10 | */ 11 | public class LineTask extends RecursiveTask { 12 | private static final long serialVersionUID = 4169105159737293155L; 13 | /** 14 | * 文档中一行数据 15 | */ 16 | private String line[]; 17 | 18 | /** 19 | * 行处理的起始位置 20 | */ 21 | private int start; 22 | /** 23 | * 行处理的结束位置 24 | */ 25 | private int end; 26 | 27 | /** 28 | * 要查找的单词 29 | */ 30 | private String word; 31 | 32 | /** 33 | * 构造函数 34 | * 35 | * @param line 文档中一行数据 36 | * @param start 行处理的起始位置 37 | * @param end 行处理的结束位置 38 | * @param word 要查找的单词 39 | */ 40 | public LineTask(String line[], int start, int end, String word) { 41 | this.line = line; 42 | this.start = start; 43 | this.end = end; 44 | this.word = word; 45 | } 46 | 47 | /** 48 | * 核心方法,完成单词的查找 49 | * 50 | * @return 查找范围内,单词出现的次数 51 | */ 52 | @Override 53 | protected Integer compute() { 54 | Integer result = null; 55 | if (end - start < 100) { // 少于100个单词就进行统计 56 | result = count(line, start, end, word); 57 | } else { // 否则就分成两个线程进行处理 58 | int mid = (start + end) / 2; 59 | LineTask task1 = new LineTask(line, start, mid + 1, word); 60 | LineTask task2 = new LineTask(line, mid + 1, end, word); 61 | invokeAll(task1, task2); 62 | 63 | try { 64 | result = groupResults(task1.get(), task2.get()); 65 | } catch (InterruptedException | ExecutionException e) { 66 | e.printStackTrace(); 67 | } 68 | } 69 | return result; 70 | } 71 | 72 | /** 73 | * 返回number1+number2的和 74 | * 75 | * @param number1 加数l 76 | * @param number2 加数2 77 | * @return 和 78 | */ 79 | private Integer groupResults(Integer number1, Integer number2) { 80 | return number1 + number2; 81 | } 82 | 83 | /** 84 | * 统计单词出现的次数 85 | * 86 | * @param line 待待查找的行 87 | * @param start 处理的开始位置 88 | * @param end 处理的结束位置 89 | * @param word 查找的单词 90 | * @return 单词出现的次数 91 | */ 92 | private Integer count(String[] line, int start, int end, String word) { 93 | int counter; 94 | counter = 0; 95 | for (int i = start; i < end; i++) { 96 | if (line[i].equals(word)) { 97 | counter++; 98 | } 99 | } 100 | try { 101 | TimeUnit.MILLISECONDS.sleep(10); 102 | } catch (InterruptedException e) { 103 | e.printStackTrace(); 104 | } 105 | return counter; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /05-03-合并任务的结果/src/com/concurrency/utils/DocumentMock.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.utils; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * 文档模拟对象,根据指定的列数和每行单词数生成文档 7 | */ 8 | public class DocumentMock { 9 | /** 10 | * 文档中的单词集合 11 | */ 12 | private String words[] = {"the", "hello", "goodbye", "packt", "java", "thread", "pool", "random", "class", "main"}; 13 | 14 | /** 15 | * 生成文档 16 | * 17 | * @param numLines 文档行数 18 | * @param numWords 每行单词数 19 | * @param word 文档中要查找的单词 20 | * @return 文档 21 | */ 22 | public String[][] generateDocument(int numLines, int numWords, String word) { 23 | 24 | int counter = 0; 25 | String document[][] = new String[numLines][numWords]; 26 | Random random = new Random(); 27 | for (int i = 0; i < numLines; i++) { 28 | for (int j = 0; j < numWords; j++) { 29 | int index = random.nextInt(words.length); 30 | document[i][j] = words[index]; 31 | if (document[i][j].equals(word)) { 32 | counter++; 33 | } 34 | } 35 | } 36 | System.out.printf("DocumentMock: The word appears %d times in the document.\n", counter); 37 | return document; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /05-04-异步运行任务/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.FolderProcessor; 4 | 5 | import java.util.List; 6 | import java.util.concurrent.ForkJoinPool; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | public class Main { 10 | public static void main(String[] args) { 11 | // 创建分合池 12 | ForkJoinPool pool = new ForkJoinPool(); 13 | 14 | // 为三个不同的文件夹创建文件处理器对象 15 | FolderProcessor system = new FolderProcessor("C:\\Windows", "log"); 16 | FolderProcessor apps = new FolderProcessor("C:\\Program Files", "log"); 17 | FolderProcessor documents = new FolderProcessor("C:\\Documents And Settings", "log"); 18 | 19 | // 在分合池中执行一个任务 20 | pool.execute(system); 21 | pool.execute(apps); 22 | pool.execute(documents); 23 | 24 | // 输出统计信息,直到三个任务都完成 25 | do { 26 | System.out.printf("******************************************\n"); 27 | System.out.printf("Main: Parallelism: %d\n", pool.getParallelism()); 28 | System.out.printf("Main: Active Threads: %d\n", pool.getActiveThreadCount()); 29 | System.out.printf("Main: Task Count: %d\n", pool.getQueuedTaskCount()); 30 | System.out.printf("Main: Steal Count: %d\n", pool.getStealCount()); 31 | System.out.printf("******************************************\n"); 32 | try { 33 | TimeUnit.SECONDS.sleep(1); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | } while ((!system.isDone()) || (!apps.isDone()) || (!documents.isDone())); 38 | 39 | // 关闭分合池 40 | pool.shutdown(); 41 | 42 | // 保存每个任务统计的结束 43 | List results; 44 | 45 | results = system.join(); 46 | System.out.printf("System: %d files found.\n", results.size()); 47 | 48 | results = apps.join(); 49 | System.out.printf("Apps: %d files found.\n", results.size()); 50 | 51 | results = documents.join(); 52 | System.out.printf("Documents: %d files found.\n", results.size()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /05-04-异步运行任务/src/com/concurrency/task/FolderProcessor.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.io.File; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.concurrent.RecursiveTask; 7 | 8 | /** 9 | * 文件夹处理类,查找指定文件夹及其子文件夹下的指定后缀名的文件 10 | */ 11 | public class FolderProcessor extends RecursiveTask> { 12 | private static final long serialVersionUID = -6119741136325003142L; 13 | /** 14 | * 开始处理的文件目录 15 | */ 16 | private String path; 17 | 18 | /** 19 | * 要查找的文件后缀名 20 | */ 21 | private String extension; 22 | 23 | /** 24 | * 构造函数 25 | * 26 | * @param path 开始处理的文件目录 27 | * @param extension 要查找的文件后缀名 28 | */ 29 | public FolderProcessor(String path, String extension) { 30 | this.path = path; 31 | this.extension = extension; 32 | } 33 | 34 | /** 35 | * 核心方法,查找文件夹下所有指定后缀的文件,如果是一个文件夹就开创建子线程去运行 36 | * 37 | * @return 查找到的文件集合 38 | */ 39 | @Override 40 | protected List compute() { 41 | List list = new ArrayList<>(); 42 | List tasks = new ArrayList<>(); 43 | File file = new File(path); 44 | File content[] = file.listFiles(); 45 | if (content != null) { 46 | for (int i = 0; i < content.length; i++) { 47 | if (content[i].isDirectory()) { 48 | FolderProcessor task = new FolderProcessor(content[i].getAbsolutePath(), extension); 49 | task.fork(); 50 | tasks.add(task); 51 | } else { 52 | if (checkFile(content[i].getName())) { 53 | list.add(content[i].getAbsolutePath()); 54 | } 55 | } 56 | } 57 | 58 | if (tasks.size() > 50) { 59 | System.out.printf("%s: %d tasks ran.\n", file.getAbsolutePath(), tasks.size()); 60 | } 61 | addResultsFromTasks(list, tasks); 62 | } 63 | 64 | return list; 65 | } 66 | 67 | /** 68 | * 汇总统计结果 69 | * 70 | * @param list 结果存放的集合 71 | * @param tasks 任务集合 72 | */ 73 | private void addResultsFromTasks(List list, List tasks) { 74 | for (FolderProcessor item : tasks) { 75 | list.addAll(item.join()); 76 | } 77 | } 78 | 79 | /** 80 | * 检查文件是否以指定的名称结束 81 | * 82 | * @param name 文件扩展名 83 | * @return true以指定的名字结束,false不以指定的名字结束 84 | */ 85 | private boolean checkFile(String name) { 86 | return name.endsWith(extension); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /05-05-在任务中抛出异常/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Task; 4 | 5 | import java.util.concurrent.ForkJoinPool; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | public class Main { 9 | public static void main(String[] args) { 10 | // 创建长度为100的整形数组 11 | int array[] = new int[100]; 12 | // 创建处理数组的任务 13 | Task task = new Task(array, 0, 100); 14 | // 创建分合池对象去执行这个任务 15 | ForkJoinPool pool = new ForkJoinPool(); 16 | 17 | // 执行任务 18 | pool.execute(task); 19 | 20 | // 关闭分合池 21 | pool.shutdown(); 22 | 23 | // 等待任务的完成 24 | try { 25 | pool.awaitTermination(1, TimeUnit.DAYS); 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } 29 | 30 | // 检查是否抛出异常,如果抛出异常就输出信息 31 | if (task.isCompletedAbnormally()) { 32 | System.out.printf("Main: An exception has ocurred\n"); 33 | System.out.printf("Main: %s\n", task.getException()); 34 | } 35 | 36 | System.out.printf("Main: Result: %d", task.join()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /05-05-在任务中抛出异常/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.RecursiveTask; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * 任务执行方法 8 | */ 9 | public class Task extends RecursiveTask { 10 | /** 11 | * 序列化版本号 12 | */ 13 | private static final long serialVersionUID = 1L; 14 | 15 | /** 16 | * 待处理的数组 17 | */ 18 | private int array[]; 19 | 20 | /** 21 | * 任务处理的起始位置 22 | */ 23 | private int start; 24 | /** 25 | * 任务处理的结束位置 26 | */ 27 | private int end; 28 | 29 | /** 30 | * 构造函数 31 | * 32 | * @param array 待处理的数组 33 | * @param start 任务处理的起始位置 34 | * @param end 任务处理的结束位置 35 | */ 36 | public Task(int array[], int start, int end) { 37 | this.array = array; 38 | this.start = start; 39 | this.end = end; 40 | } 41 | 42 | /** 43 | * 核心方法,如果处理的元素大于9个就分成两个任务去执行它,如果处理的起始位置小于3,结束位置大于3就抛出异常 44 | */ 45 | @Override 46 | protected Integer compute() { 47 | System.out.printf("Task: Start from %d to %d\n", start, end); 48 | if (end - start < 10) { 49 | if ((3 > start) && (3 < end)) { 50 | throw new RuntimeException("This task throws an Exception: Task from " + start + " to " + end); 51 | } 52 | 53 | try { 54 | TimeUnit.SECONDS.sleep(1); 55 | } catch (InterruptedException e) { 56 | e.printStackTrace(); 57 | } 58 | 59 | } else { 60 | int mid = (end + start) / 2; 61 | Task task1 = new Task(array, start, mid); 62 | Task task2 = new Task(array, mid, end); 63 | invokeAll(task1, task2); 64 | System.out.printf("Task: Result form %d to %d: %d\n", start, mid, task1.join()); 65 | System.out.printf("Task: Result form %d to %d: %d\n", mid, end, task2.join()); 66 | } 67 | System.out.printf("Task: End form %d to %d\n", start, end); 68 | return 0; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /05-06-取消任务/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.TaskManager; 4 | import com.concurrency.utils.ArrayGenerator; 5 | import com.concurrency.utils.SearchNumberTask; 6 | 7 | import java.util.concurrent.ForkJoinPool; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class Main { 11 | public static void main(String[] args) { 12 | // 创建一个数组生成器对象,生成一个长度为1000的整形数组 13 | ArrayGenerator generator = new ArrayGenerator(); 14 | int array[] = generator.generateArray(1000); 15 | 16 | // 创建一个任务管理对象 17 | TaskManager manager = new TaskManager(); 18 | 19 | // 使用默认的构造函数,创建一个分合池对象 20 | ForkJoinPool pool = new ForkJoinPool(); 21 | 22 | // 创建一个处理任务的数组 23 | SearchNumberTask task = new SearchNumberTask(array, 0, 1000, 5, manager); 24 | 25 | //执行任务 26 | pool.execute(task); 27 | 28 | // 关闭这个池 29 | pool.shutdown(); 30 | 31 | 32 | // 等待任务完成 33 | try { 34 | pool.awaitTermination(1, TimeUnit.DAYS); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | 39 | // 输出信息,表示程序已经完成 40 | System.out.printf("Main: The program has finished\n"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /05-06-取消任务/src/com/concurrency/task/TaskManager.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.utils.SearchNumberTask; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.concurrent.ForkJoinTask; 8 | 9 | /** 10 | * 任务管理类 11 | */ 12 | public class TaskManager { 13 | /** 14 | * 任务列表对象 15 | */ 16 | private List> tasks; 17 | 18 | /** 19 | * 构造函数,初始化任务值列表对象 20 | */ 21 | public TaskManager(){ 22 | tasks=new ArrayList<>(); 23 | } 24 | 25 | /** 26 | * 在列表中添加一个新的任务 27 | * @param task 新的任务 28 | */ 29 | public void addTask(ForkJoinTask task){ 30 | tasks.add(task); 31 | } 32 | 33 | /** 34 | * 取消队列中的指定任务 35 | * @param cancelTask 指定的任务 36 | */ 37 | public void cancelTasks(ForkJoinTask cancelTask){ 38 | for (ForkJoinTask task :tasks) { 39 | if (task!=cancelTask) { 40 | task.cancel(true); 41 | ((SearchNumberTask)task).writeCancelMessage(); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /05-06-取消任务/src/com/concurrency/utils/ArrayGenerator.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.utils; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * 整形数组生成类 7 | */ 8 | public class ArrayGenerator { 9 | /** 10 | * 生成整形数组,生成的值在[0, size) 11 | * @param size 数组长度 12 | * @return 长度为size的数组 13 | */ 14 | public int[] generateArray(int size) { 15 | int array[] = new int[size]; 16 | Random random = new Random(); 17 | for (int i = 0; i < size; i++) { 18 | array[i] = random.nextInt(10); 19 | } 20 | return array; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /06-02-使用非阻塞式线程安全列表/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.AddTask; 4 | import com.concurrency.task.PollTask; 5 | 6 | import java.util.concurrent.ConcurrentLinkedDeque; 7 | 8 | public class Main { 9 | public static void main(String[] args) throws Exception { 10 | // 创建一个并发双向队列对象 11 | ConcurrentLinkedDeque list = new ConcurrentLinkedDeque<>(); 12 | // 创建长度为100的线程数组 13 | Thread threads[] = new Thread[100]; 14 | 15 | // 创建100个AddTask对象,并且让他们在各自的线程中运行 16 | for (int i = 0; i < threads.length; i++) { 17 | AddTask task = new AddTask(list); 18 | threads[i] = new Thread(task); 19 | threads[i].start(); 20 | } 21 | System.out.printf("Main: %d AddTask threads have been launched\n", threads.length); 22 | 23 | // 等待所有的线程执行完 24 | for (Thread thread : threads) { 25 | thread.join(); 26 | } 27 | 28 | // 输出队列长度信息 29 | System.out.printf("Main: Size of the List: %d\n", list.size()); 30 | 31 | // 创建100个PollTask对象,并且让他们在各自的线程中运行 32 | for (int i = 0; i < threads.length; i++) { 33 | PollTask task = new PollTask(list); 34 | threads[i] = new Thread(task); 35 | threads[i].start(); 36 | } 37 | System.out.printf("Main: %d PollTask threads have been launched\n", threads.length); 38 | 39 | // 等待线程执行完 40 | for (Thread thread : threads) { 41 | thread.join(); 42 | } 43 | 44 | // 输出队列长度信息 45 | System.out.printf("Main: Size of the List: %d\n", list.size()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /06-02-使用非阻塞式线程安全列表/src/com/concurrency/task/AddTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.ConcurrentLinkedDeque; 4 | 5 | /** 6 | * 添加数据任务类,向并发队列中添加10000个数据 7 | */ 8 | public class AddTask implements Runnable { 9 | 10 | /** 11 | * 等待添加数组的队列 12 | */ 13 | private ConcurrentLinkedDeque list; 14 | 15 | /** 16 | * 构造函数 17 | * 18 | * @param list 等待添加数组的队列 19 | */ 20 | public AddTask(ConcurrentLinkedDeque list) { 21 | this.list = list; 22 | } 23 | 24 | /** 25 | * 核心方法,向并发队列中添加10000个数据 26 | */ 27 | @Override 28 | public void run() { 29 | String name = Thread.currentThread().getName(); 30 | for (int i = 0; i < 10000; i++) { 31 | list.add(name + ": Element " + i); 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /06-02-使用非阻塞式线程安全列表/src/com/concurrency/task/PollTask.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.ConcurrentLinkedDeque; 4 | 5 | /** 6 | * 取数据任务类,从并发队列中删除10000个数据 7 | */ 8 | public class PollTask implements Runnable { 9 | 10 | /** 11 | * 待删除元素的队列 12 | */ 13 | private ConcurrentLinkedDeque list; 14 | 15 | /** 16 | * 构造函数 17 | * 18 | * @param list 待删除元素的队列 19 | */ 20 | public PollTask(ConcurrentLinkedDeque list) { 21 | this.list = list; 22 | } 23 | 24 | /** 25 | * 核心方法,在并发队列的头部和尾部各删除5000个元素 26 | */ 27 | @Override 28 | public void run() { 29 | for (int i = 0; i < 5000; i++) { 30 | list.pollFirst(); 31 | list.pollLast(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /06-03-使用阻塞式线程安全列表/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Client; 4 | 5 | import java.util.Date; 6 | import java.util.concurrent.LinkedBlockingDeque; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | public class Main { 10 | public static void main(String[] args) throws Exception { 11 | // 创建一个并发链式双向队列 12 | LinkedBlockingDeque list = new LinkedBlockingDeque<>(3); 13 | 14 | Client client = new Client(list); 15 | Thread thread = new Thread(client); 16 | thread.start(); 17 | 18 | for (int i = 0; i < 5; i++) { 19 | for (int j = 0; j < 3; j++) { 20 | String request = list.take(); 21 | System.out.printf("Main: Request: %s at %s. Size: %d\n", request, new Date(), list.size()); 22 | } 23 | TimeUnit.MILLISECONDS.sleep(300); 24 | } 25 | 26 | System.out.printf("Main: End of the program.\n"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /06-03-使用阻塞式线程安全列表/src/com/concurrency/task/Client.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/06-03-使用阻塞式线程安全列表/src/com/concurrency/task/Client.java -------------------------------------------------------------------------------- /06-04-使用按优先级排序的阻塞式线程安全列表/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Event; 4 | import com.concurrency.task.Task; 5 | 6 | import java.util.concurrent.PriorityBlockingQueue; 7 | 8 | public class Main { 9 | public static void main(String[] args) { 10 | 11 | // 存储事件的优先级队列 12 | PriorityBlockingQueue queue = new PriorityBlockingQueue<>(); 13 | 14 | 15 | // 存储5个线程对象的数组 16 | Thread taskThreads[] = new Thread[5]; 17 | 18 | 19 | // 创建5个线程运行5个任务,每个任务创建1000事件对象 20 | for (int i = 0; i < taskThreads.length; i++) { 21 | Task task = new Task(i, queue); 22 | taskThreads[i] = new Thread(task); 23 | } 24 | 25 | 26 | // 启动5个线程 27 | for (Thread taskThread : taskThreads) { 28 | taskThread.start(); 29 | } 30 | 31 | // 等待5个线程完成 32 | for (Thread taskThread : taskThreads) { 33 | try { 34 | taskThread.join(); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | // 输出事件信息 41 | System.out.printf("Main: Queue Size: %d\n", queue.size()); 42 | for (int i = 0; i < taskThreads.length * 1000; i++) { 43 | Event event = queue.poll(); 44 | System.out.printf("Thread %s: Priority %d\n", event.getThread(), event.getPriority()); 45 | } 46 | System.out.printf("Main: Queue Size: %d\n", queue.size()); 47 | System.out.printf("Main: End of the program\n"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /06-04-使用按优先级排序的阻塞式线程安全列表/src/com/concurrency/task/Event.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.sun.istack.internal.NotNull; 4 | 5 | /** 6 | * 事件类,存储一个件事的属性,它包括一个事件的优先级,这个类实现了Comparable接口的方法, 7 | * 用来确定哪个事件对象的优先级更高 8 | */ 9 | public class Event implements Comparable { 10 | 11 | /** 12 | * 线程编号 13 | */ 14 | private int thread; 15 | /** 16 | * 线程优先级 17 | */ 18 | private int priority; 19 | 20 | /** 21 | * 构造构造,用于初始化属性 22 | * 23 | * @param thread 产生事件的线程编号 24 | * @param priority 事件的优先级 25 | */ 26 | public Event(int thread, int priority) { 27 | this.thread = thread; 28 | this.priority = priority; 29 | } 30 | 31 | /** 32 | * 获取线程编号 33 | * 34 | * @return 线程编号 35 | */ 36 | public int getThread() { 37 | return thread; 38 | } 39 | 40 | /** 41 | * 获取线程优先级 42 | * 43 | * @return 线程优先级 44 | */ 45 | public int getPriority() { 46 | return priority; 47 | } 48 | 49 | /** 50 | * 比较那个线程的优先级更高 51 | */ 52 | @Override 53 | public int compareTo(Event e) { 54 | if (this.priority > e.getPriority()) { 55 | return -1; 56 | } else if (this.priority < e.getPriority()) { 57 | return 1; 58 | } else { 59 | return 0; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /06-04-使用按优先级排序的阻塞式线程安全列表/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.PriorityBlockingQueue; 4 | 5 | /** 6 | * 任务对象,生成1000个事件,并且将其存放在一个优先队列中 7 | */ 8 | public class Task implements Runnable { 9 | 10 | /** 11 | * 任务编号 12 | */ 13 | private int id; 14 | 15 | /** 16 | * 存储事件的优先队列 17 | */ 18 | private PriorityBlockingQueue queue; 19 | 20 | /** 21 | * 构造函数,初始化属性 22 | * 23 | * @param id 任务编号 24 | * @param queue 存储事件的优先队列 25 | */ 26 | public Task(int id, PriorityBlockingQueue queue) { 27 | this.id = id; 28 | this.queue = queue; 29 | } 30 | 31 | /** 32 | * 核心方法,生成1000个事件,并且将其存放在一个优先队列中 33 | */ 34 | @Override 35 | public void run() { 36 | for (int i = 0; i < 1000; i++) { 37 | Event event = new Event(id, i); 38 | queue.add(event); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /06-05-使用带有延迟元素的线程安全列表/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Event; 4 | import com.concurrency.task.Task; 5 | 6 | import java.util.Date; 7 | import java.util.concurrent.DelayQueue; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class Main { 11 | public static void main(String[] args) throws Exception { 12 | // 存储事件的延迟队列 13 | DelayQueue queue = new DelayQueue<>(); 14 | 15 | // 线程数组 16 | Thread threads[] = new Thread[5]; 17 | 18 | // 创建5个任务对象,并且放在不同的线程中去执行 19 | for (int i = 0; i < threads.length; i++) { 20 | Task task = new Task(i + 1, queue); 21 | threads[i] = new Thread(task); 22 | } 23 | 24 | // 启动线程 25 | for (Thread thread : threads) { 26 | thread.start(); 27 | } 28 | 29 | // 等待5个任务的完成 30 | for (Thread thread : threads) { 31 | thread.join(); 32 | } 33 | 34 | // 输出结果 35 | do { 36 | int counter = 0; 37 | Event event; 38 | do { // 取队列中的所有数据 39 | event = queue.poll(); 40 | if (event != null) { 41 | counter++; 42 | } 43 | } while (event != null); 44 | System.out.printf("At %s you have read %d events\n", new Date(), counter); 45 | TimeUnit.MILLISECONDS.sleep(500); 46 | } while (queue.size() > 0); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /06-05-使用带有延迟元素的线程安全列表/src/com/concurrency/task/Event.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.Delayed; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * 事件类,实现了延迟队列接口 9 | */ 10 | public class Event implements Delayed { 11 | 12 | /** 13 | * 激活事件的时间 14 | */ 15 | private Date startDate; 16 | 17 | /** 18 | * 构造函数 19 | * 20 | * @param startDate 激活事件的时间 21 | */ 22 | public Event(Date startDate) { 23 | this.startDate = startDate; 24 | } 25 | 26 | /** 27 | * 比较两个事件 28 | */ 29 | @Override 30 | public int compareTo(Delayed o) { 31 | long result = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS); 32 | if (result < 0) { 33 | return -1; 34 | } else if (result > 0) { 35 | return 1; 36 | } 37 | return 0; 38 | } 39 | 40 | /** 41 | * 返回离激活时间还剩余的毫秒数 42 | */ 43 | @Override 44 | public long getDelay(TimeUnit unit) { 45 | Date now = new Date(); 46 | long diff = startDate.getTime() - now.getTime(); 47 | return unit.convert(diff, TimeUnit.MILLISECONDS); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /06-05-使用带有延迟元素的线程安全列表/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.DelayQueue; 5 | 6 | /** 7 | * 任务类,其事件存储在一个延迟队列中 8 | */ 9 | public class Task implements Runnable { 10 | 11 | /** 12 | * 任务编号 13 | */ 14 | private int id; 15 | 16 | /** 17 | * 存储事件的任务队列 18 | */ 19 | private DelayQueue queue; 20 | 21 | /** 22 | * 构造函数,初始化属性 23 | * 24 | * @param id 任务编号 25 | * @param queue 存储事件的任务队列 26 | */ 27 | public Task(int id, DelayQueue queue) { 28 | this.id = id; 29 | this.queue = queue; 30 | } 31 | 32 | 33 | /** 34 | * 核心方法,产生100事件,每个事件有相同的激活时间,将这些事件存储在延迟队列中 35 | */ 36 | @Override 37 | public void run() { 38 | 39 | Date now = new Date(); 40 | Date delay = new Date(); 41 | delay.setTime(now.getTime() + (id * 1000)); 42 | 43 | System.out.printf("Thread %s: %s\n", id, delay); 44 | 45 | for (int i = 0; i < 100; i++) { 46 | Event event = new Event(delay); 47 | queue.add(event); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /06-06-使用线程安全可遍历映射/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Task; 4 | import com.concurrency.utils.Contact; 5 | 6 | import java.util.Map; 7 | import java.util.concurrent.ConcurrentNavigableMap; 8 | import java.util.concurrent.ConcurrentSkipListMap; 9 | 10 | public class Main { 11 | public static void main(String[] args) { 12 | // 创建一个可遍历的映射对象 13 | ConcurrentSkipListMap map; 14 | map = new ConcurrentSkipListMap<>(); 15 | 16 | // 创建长度为25的线程数组 17 | Thread threads[] = new Thread[25]; 18 | int counter = 0; 19 | 20 | // 在25个不同的线程中执行25个任务 21 | for (char i = 'A'; i < 'Z'; i++) { 22 | Task task = new Task(map, String.valueOf(i)); 23 | threads[counter] = new Thread(task); 24 | threads[counter].start(); 25 | counter++; 26 | } 27 | 28 | // 等待任务执行完成 29 | for (Thread thread : threads) { 30 | try { 31 | thread.join(); 32 | } catch (InterruptedException e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | 37 | // 输出映射的大小 38 | System.out.printf("Main: Size of the map: %d\n", map.size()); 39 | 40 | // 保存映射条目的对象 41 | Map.Entry element; 42 | // 保存联系人的对象 43 | Contact contact; 44 | 45 | element = map.firstEntry(); 46 | contact = element.getValue(); 47 | System.out.printf("Main: First Entry: %s: %s\n", contact.getName(), contact.getPhone()); 48 | 49 | // 输出最后一个映射条目 50 | element = map.lastEntry(); 51 | contact = element.getValue(); 52 | System.out.printf("Main: Last Entry: %s: %s\n", contact.getName(), contact.getPhone()); 53 | 54 | // 输出映射的字集 55 | System.out.printf("Main: Submap from A1996 to B1002: \n"); 56 | ConcurrentNavigableMap submap = map.subMap("A1996", "B1002"); 57 | do { 58 | element = submap.pollFirstEntry(); 59 | if (element != null) { 60 | contact = element.getValue(); 61 | System.out.printf("%s: %s\n", contact.getName(), contact.getPhone()); 62 | } 63 | } while (element != null); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /06-06-使用线程安全可遍历映射/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import com.concurrency.utils.Contact; 4 | 5 | import java.util.concurrent.ConcurrentSkipListMap; 6 | 7 | /** 8 | * 任务类,将联系人存储在一个可遍历的图中 9 | */ 10 | public class Task implements Runnable { 11 | 12 | /** 13 | * 存储联系人的可遍历的映射 14 | */ 15 | private ConcurrentSkipListMap map; 16 | 17 | /** 18 | * 任务编号 19 | */ 20 | private String id; 21 | 22 | /** 23 | * 构造函数,初始化属性 24 | * 25 | * @param map 存储联系人的可遍历的映射 26 | * @param id 任务编号 27 | */ 28 | public Task(ConcurrentSkipListMap map, String id) { 29 | this.id = id; 30 | this.map = map; 31 | } 32 | 33 | /** 34 | * 核心方法,产生1000个联系人,并且交它们存储在一个可遍历的映射中 35 | */ 36 | @Override 37 | public void run() { 38 | for (int i = 0; i < 1000; i++) { 39 | Contact contact = new Contact(id, String.valueOf(i + 1000)); 40 | map.put(id + contact.getPhone(), contact); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /06-06-使用线程安全可遍历映射/src/com/concurrency/utils/Contact.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.utils; 2 | 3 | /** 4 | * 联系人类 5 | */ 6 | public class Contact { 7 | 8 | /** 9 | * 联系人的名称 10 | */ 11 | private String name; 12 | 13 | /** 14 | * 联系人的电话 15 | */ 16 | private String phone; 17 | 18 | /** 19 | * 构造函数 20 | * 21 | * @param name 联系人的名称 22 | * @param phone 联系人的电话 23 | */ 24 | public Contact(String name, String phone) { 25 | this.name = name; 26 | this.phone = phone; 27 | } 28 | 29 | /** 30 | * 获取 联系人的名称 31 | * 32 | * @return 联系人的名称 33 | */ 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | /** 39 | * 获取联系人的电话 40 | * 41 | * @return 联系人的电话 42 | */ 43 | public String getPhone() { 44 | return phone; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /06-07-生成并发随机数/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.TaskLocalRandom; 4 | 5 | public class Main { 6 | public static void main(String[] args) { 7 | // 长度为3的线程数组 8 | Thread threads[] = new Thread[3]; 9 | 10 | // 创建线程并且运行任务 11 | for (int i = 0; i < threads.length; i++) { 12 | TaskLocalRandom task = new TaskLocalRandom(); 13 | threads[i] = new Thread(task); 14 | threads[i].start(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /06-07-生成并发随机数/src/com/concurrency/task/TaskLocalRandom.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.ThreadLocalRandom; 4 | 5 | /** 6 | * 产生随机数的任务类 7 | */ 8 | public class TaskLocalRandom implements Runnable { 9 | 10 | /** 11 | * 构造函数,初始化当前类的随机数生成对象 12 | */ 13 | public TaskLocalRandom() { 14 | ThreadLocalRandom.current(); 15 | } 16 | 17 | /** 18 | * 核心方法,生成一个[0, 10)的随机数 19 | */ 20 | @Override 21 | public void run() { 22 | String name = Thread.currentThread().getName(); 23 | for (int i = 0; i < 10; i++) { 24 | System.out.printf("%s: %d\n", name, ThreadLocalRandom.current().nextInt(10)); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /06-08-使用原子变量/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Account; 4 | import com.concurrency.task.Bank; 5 | import com.concurrency.task.Company; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | // 创建一个帐户对象 10 | Account account = new Account(); 11 | // 初始化帐户余额 12 | account.setBalance(1000); 13 | 14 | // 创建一个公司对象,并且将公司对象放到线程中去运行 15 | Company company = new Company(account); 16 | Thread companyThread = new Thread(company); 17 | // 创建一个银行对象,并且将银行对象放到线程中去运行 18 | Bank bank = new Bank(account); 19 | Thread bankThread = new Thread(bank); 20 | 21 | // 输出帐户对象最初的信息 22 | System.out.printf("Account : Initial Balance: %d\n", account.getBalance()); 23 | 24 | // 启动线程 25 | companyThread.start(); 26 | bankThread.start(); 27 | 28 | try { 29 | // 等待线程完成 30 | companyThread.join(); 31 | bankThread.join(); 32 | // 输出余额 33 | System.out.printf("Account : Final Balance: %d\n", account.getBalance()); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /06-08-使用原子变量/src/com/concurrency/task/Account.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | 5 | /** 6 | * 帐户类 7 | */ 8 | public class Account { 9 | 10 | /** 11 | * 帐户余额 12 | */ 13 | private AtomicLong balance; 14 | 15 | public Account() { 16 | balance = new AtomicLong(); 17 | } 18 | 19 | /** 20 | */ 21 | /** 22 | * 获取帐户余额 23 | * 24 | * @return 帐户余额 25 | */ 26 | public long getBalance() { 27 | return balance.get(); 28 | } 29 | 30 | /** 31 | * 设置帐户余额 32 | * 33 | * @param balance 帐户余额 34 | */ 35 | public void setBalance(long balance) { 36 | this.balance.set(balance); 37 | } 38 | 39 | /** 40 | * 增加余额 41 | * 42 | * @param amount 增加的数目 43 | */ 44 | public void addAmount(long amount) { 45 | this.balance.getAndAdd(amount); 46 | } 47 | 48 | /** 49 | * 减少余额 50 | * 51 | * @param amount 减少的数目 52 | */ 53 | public void subtractAmount(long amount) { 54 | this.balance.getAndAdd(-amount); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /06-08-使用原子变量/src/com/concurrency/task/Bank.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 银行帐户类,模拟从一个帐户上取钱 5 | */ 6 | public class Bank implements Runnable { 7 | 8 | /** 9 | * 帐户对象 10 | */ 11 | private Account account; 12 | 13 | /** 14 | * 构造函数,初始化帐户属性 15 | * 16 | * @param account 帐户对象 17 | */ 18 | public Bank(Account account) { 19 | this.account = account; 20 | } 21 | 22 | 23 | /** 24 | * 核心方法,取钱 25 | */ 26 | @Override 27 | public void run() { 28 | for (int i = 0; i < 10; i++) { 29 | account.subtractAmount(1000); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /06-08-使用原子变量/src/com/concurrency/task/Company.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | /** 4 | * 公司类,模拟向一个帐户存钱 5 | */ 6 | public class Company implements Runnable { 7 | 8 | /** 9 | * 帐户对象 10 | */ 11 | private Account account; 12 | 13 | /** 14 | * 构造函数,初始化帐户属性 15 | * 16 | * @param account 帐户对象 17 | */ 18 | public Company(Account account) { 19 | this.account = account; 20 | } 21 | 22 | /** 23 | * 核心方法,存钱 24 | */ 25 | @Override 26 | public void run() { 27 | for (int i = 0; i < 10; i++) { 28 | account.addAmount(1000); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /06-09-使用原子数组/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Decrementer; 4 | import com.concurrency.task.Incrementer; 5 | 6 | import java.util.concurrent.atomic.AtomicIntegerArray; 7 | 8 | public class Main { 9 | public static void main(String[] args) { 10 | // 线程个数 11 | final int THREADS = 100; 12 | // 原子数组对象,它有1000个元素 13 | AtomicIntegerArray vector = new AtomicIntegerArray(1000); 14 | // 创建一个加法器对象 15 | Incrementer incrementer = new Incrementer(vector); 16 | // 创建一个减法器对象 17 | Decrementer decrementer = new Decrementer(vector); 18 | 19 | // 创建并且执行100个加法线程和100个减法线程 20 | Thread threadIncrementer[] = new Thread[THREADS]; 21 | Thread threadDecrementer[] = new Thread[THREADS]; 22 | for (int i = 0; i < THREADS; i++) { 23 | threadIncrementer[i] = new Thread(incrementer); 24 | threadDecrementer[i] = new Thread(decrementer); 25 | 26 | threadIncrementer[i].start(); 27 | threadDecrementer[i].start(); 28 | } 29 | 30 | // 等待所有的任务完成 31 | for (int i = 0; i < THREADS; i++) { 32 | try { 33 | threadIncrementer[i].join(); 34 | threadDecrementer[i].join(); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | // 输出不为0的元素 41 | for (int i = 0; i < vector.length(); i++) { 42 | if (vector.get(i) != 0) { 43 | System.out.println("Vector[" + i + "] : " + vector.get(i)); 44 | } 45 | } 46 | 47 | System.out.println("Main: End of the example"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /06-09-使用原子数组/src/com/concurrency/task/Decrementer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.atomic.AtomicIntegerArray; 4 | 5 | /** 6 | * 减法器,将数组中的每元素减少指定个单位 7 | */ 8 | public class Decrementer implements Runnable { 9 | 10 | /** 11 | * 要执行减法的数组 12 | */ 13 | private AtomicIntegerArray vector; 14 | 15 | /** 16 | * 构造函数 17 | * 18 | * @param vector 要执行减法的数组 19 | */ 20 | public Decrementer(AtomicIntegerArray vector) { 21 | this.vector = vector; 22 | } 23 | 24 | /** 25 | * 核心方法, 将数组中的每元素减少指定个单位 26 | */ 27 | @Override 28 | public void run() { 29 | for (int i = 0; i < vector.length(); i++) { 30 | vector.getAndDecrement(i); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /06-09-使用原子数组/src/com/concurrency/task/Incrementer.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.task; 2 | 3 | import java.util.concurrent.atomic.AtomicIntegerArray; 4 | 5 | /** 6 | * 加法器,将数组中的每元素增加指定个单位 7 | */ 8 | public class Incrementer implements Runnable { 9 | 10 | /** 11 | * 要执行加法的数组 12 | */ 13 | private AtomicIntegerArray vector; 14 | 15 | /** 16 | * 构造函数 17 | * 18 | * @param vector 要执行加法的数组 19 | */ 20 | public Incrementer(AtomicIntegerArray vector) { 21 | this.vector = vector; 22 | } 23 | 24 | /** 25 | * 核心方法,将数组中的每元素增加指定个单位 26 | */ 27 | @Override 28 | public void run() { 29 | 30 | for (int i = 0; i < vector.length(); i++) { 31 | vector.getAndIncrement(i); 32 | } 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /07-02-定制ThreadPoolExecutor类/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.executor.MyExecutor; 4 | import com.concurrency.task.SleepTwoSecondsTask; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.concurrent.ExecutionException; 9 | import java.util.concurrent.Future; 10 | import java.util.concurrent.LinkedBlockingDeque; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | public class Main { 14 | public static void main(String[] args) { 15 | // 创建一个定制的线程执行器 16 | MyExecutor myExecutor = new MyExecutor(2, 4, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque()); 17 | 18 | // 创建一个队列来存存储任务的执行结果 19 | List> results = new ArrayList<>(); 20 | 21 | // 创建并且提交10个任务 22 | for (int i = 0; i < 10; i++) { 23 | SleepTwoSecondsTask task = new SleepTwoSecondsTask(); 24 | Future result = myExecutor.submit(task); 25 | results.add(result); 26 | } 27 | 28 | // 获取前5个的执行结果 29 | for (int i = 0; i < 5; i++) { 30 | try { 31 | String result = results.get(i).get(); 32 | System.out.printf("Main: Result for Task %d : %s\n", i, result); 33 | } catch (InterruptedException | ExecutionException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | 38 | // 关闭线执行器 39 | myExecutor.shutdown(); 40 | 41 | // 获取后5个的执行结果 42 | for (int i = 5; i < 10; i++) { 43 | try { 44 | String result = results.get(i).get(); 45 | System.out.printf("Main: Result for Task %d : %s\n", i, result); 46 | } catch (InterruptedException | ExecutionException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | 51 | // 等待执行器执行完 52 | try { 53 | myExecutor.awaitTermination(1, TimeUnit.DAYS); 54 | } catch (InterruptedException e) { 55 | e.printStackTrace(); 56 | } 57 | 58 | // 输出信息,表示整个程序运行结束 59 | System.out.printf("Main: End of the program.\n"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /07-02-定制ThreadPoolExecutor类/src/com/concurrency/executor/MyExecutor.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-02-定制ThreadPoolExecutor类/src/com/concurrency/executor/MyExecutor.java -------------------------------------------------------------------------------- /07-02-定制ThreadPoolExecutor类/src/com/concurrency/task/SleepTwoSecondsTask.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-02-定制ThreadPoolExecutor类/src/com/concurrency/task/SleepTwoSecondsTask.java -------------------------------------------------------------------------------- /07-03-基于优先级的Executor类/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-03-基于优先级的Executor类/src/com/concurrency/core/Main.java -------------------------------------------------------------------------------- /07-03-基于优先级的Executor类/src/com/concurrency/task/MyPriorityTask.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-03-基于优先级的Executor类/src/com/concurrency/task/MyPriorityTask.java -------------------------------------------------------------------------------- /07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/core/Main.java -------------------------------------------------------------------------------- /07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyTask.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyTask.java -------------------------------------------------------------------------------- /07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThread.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThread.java -------------------------------------------------------------------------------- /07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThreadFactory.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-04-实现ThreadFactory接口生成定制线程/src/com/concurrency/task/MyThreadFactory.java -------------------------------------------------------------------------------- /07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/core/Main.java -------------------------------------------------------------------------------- /07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyTask.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyTask.java -------------------------------------------------------------------------------- /07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThread.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThread.java -------------------------------------------------------------------------------- /07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThreadFactory.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-05-在Executro对象中使用ThreadFactory/src/com/concurrency/task/MyThreadFactory.java -------------------------------------------------------------------------------- /07-06-定制运行在线程池中的任务/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-06-定制运行在线程池中的任务/src/com/concurrency/core/Main.java -------------------------------------------------------------------------------- /07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledTask.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledTask.java -------------------------------------------------------------------------------- /07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledThreadPoolExecutor.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-06-定制运行在线程池中的任务/src/com/concurrency/task/MyScheduledThreadPoolExecutor.java -------------------------------------------------------------------------------- /07-06-定制运行在线程池中的任务/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-06-定制运行在线程池中的任务/src/com/concurrency/task/Task.java -------------------------------------------------------------------------------- /07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/core/Main.java -------------------------------------------------------------------------------- /07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyRecursiveTask.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyRecursiveTask.java -------------------------------------------------------------------------------- /07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThread.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThread.java -------------------------------------------------------------------------------- /07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThreadFactory.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-07-通过实现ThreadFactory接口为Fork-Join框架生成定制线程/src/com/concurrency/task/MyWorkerThreadFactory.java -------------------------------------------------------------------------------- /07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/core/Main.java -------------------------------------------------------------------------------- /07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/MyWorkerTask.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/MyWorkerTask.java -------------------------------------------------------------------------------- /07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-08-定制运行在Fork-Join框架中的任务/src/com/concurrency/task/Task.java -------------------------------------------------------------------------------- /07-09-现实定制Lock类/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-09-现实定制Lock类/src/com/concurrency/core/Main.java -------------------------------------------------------------------------------- /07-09-现实定制Lock类/src/com/concurrency/task/MyAbstractQueuedSynchronizer.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-09-现实定制Lock类/src/com/concurrency/task/MyAbstractQueuedSynchronizer.java -------------------------------------------------------------------------------- /07-09-现实定制Lock类/src/com/concurrency/task/MyLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-09-现实定制Lock类/src/com/concurrency/task/MyLock.java -------------------------------------------------------------------------------- /07-09-现实定制Lock类/src/com/concurrency/task/Task.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-09-现实定制Lock类/src/com/concurrency/task/Task.java -------------------------------------------------------------------------------- /07-10-实现基于优先级的传输队列/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- 1 | package com.concurrency.core; 2 | 3 | import com.concurrency.task.Consumer; 4 | import com.concurrency.task.Event; 5 | import com.concurrency.task.MyPriorityTransferQueue; 6 | import com.concurrency.task.Producer; 7 | 8 | import java.util.concurrent.TimeUnit; 9 | 10 | 11 | public class Main { 12 | 13 | public static void main(String[] args) throws Exception { 14 | 15 | MyPriorityTransferQueue buffer = new MyPriorityTransferQueue<>(); 16 | Producer producer = new Producer(buffer); 17 | 18 | Thread producerThreads[] = new Thread[10]; 19 | for (int i = 0; i < producerThreads.length; i++) { 20 | producerThreads[i] = new Thread(producer); 21 | producerThreads[i].start(); 22 | } 23 | 24 | Consumer consumer = new Consumer(buffer); 25 | Thread consumerThread = new Thread(consumer); 26 | consumerThread.start(); 27 | 28 | System.out.printf("Main: Buffer: Consumer count: %d\n", buffer.getWaitingConsumerCount()); 29 | 30 | 31 | Event myEvent = new Event("Core Event", 0); 32 | buffer.transfer(myEvent); 33 | System.out.printf("Main: My Event has ben transfered.\n"); 34 | 35 | 36 | for (int i = 0; i < producerThreads.length; i++) { 37 | producerThreads[i].join(); 38 | } 39 | 40 | TimeUnit.SECONDS.sleep(1); 41 | 42 | System.out.printf("Main: Buffer: Consumer count: %d\n", buffer.getWaitingConsumerCount()); 43 | 44 | myEvent = new Event("Core Event 2", 0); 45 | buffer.transfer(myEvent); 46 | 47 | consumerThread.join(); 48 | 49 | System.out.printf("Main: End of the program\n"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /07-10-实现基于优先级的传输队列/src/com/concurrency/task/Consumer.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-10-实现基于优先级的传输队列/src/com/concurrency/task/Consumer.java -------------------------------------------------------------------------------- /07-10-实现基于优先级的传输队列/src/com/concurrency/task/Event.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-10-实现基于优先级的传输队列/src/com/concurrency/task/Event.java -------------------------------------------------------------------------------- /07-10-实现基于优先级的传输队列/src/com/concurrency/task/MyPriorityTransferQueue.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-10-实现基于优先级的传输队列/src/com/concurrency/task/MyPriorityTransferQueue.java -------------------------------------------------------------------------------- /07-10-实现基于优先级的传输队列/src/com/concurrency/task/Producer.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-10-实现基于优先级的传输队列/src/com/concurrency/task/Producer.java -------------------------------------------------------------------------------- /07-11-实现自己的原子对象/src/com/concurrency/core/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-11-实现自己的原子对象/src/com/concurrency/core/Main.java -------------------------------------------------------------------------------- /07-11-实现自己的原子对象/src/com/concurrency/task/ParkingCounter.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-11-实现自己的原子对象/src/com/concurrency/task/ParkingCounter.java -------------------------------------------------------------------------------- /07-11-实现自己的原子对象/src/com/concurrency/task/Sensor1.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-11-实现自己的原子对象/src/com/concurrency/task/Sensor1.java -------------------------------------------------------------------------------- /07-11-实现自己的原子对象/src/com/concurrency/task/Sensor2.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wang-Jun-Chao/java-concurrency/80f41b043fd83a96cc68eadc0b2429d6aae5747e/07-11-实现自己的原子对象/src/com/concurrency/task/Sensor2.java -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # java 7 并发编程实战手册 2 | --------------------------------------------------------------------------------