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