并发API提供的一个有趣功能是可以将多个线程组成一个组。
这样我们就能将这一组线程看做一个单元并且提供改组内线程对象的读取操作。例如
Java提供了一个ThreadGroup类来表示一组线程。一个线程组对象由多个线程对象和另一个线程组对象组成,从而形成树状的线程结构。
本例中,我们将学习使用ThreadGroup对象开发一个简单例子。我们有10个线程模拟搜索(随机睡眠一段时间),并且其中一个执行结束,我们将打断其余线程。
Result.java
package com.dylan.thread.ch1.c10.task; /** * Class that stores the result of the search * */ public class Result { /** * Name of the Thread that finish */ private String name; /** * Read the name of the Thread * @return The name of the Thread */ public String getName() { return name; } /** * Write the name of the Thread * @param name The name of the Thread */ public void setName(String name) { this.name = name; } }
SearchTask.java
package com.dylan.thread.ch1.c10.task; import java.util.Date; import java.util.Random; import java.util.concurrent.TimeUnit; /** * Class that simulates a search operation * */ public class SearchTask implements Runnable { /** * Store the name of the Thread if this Thread finish and is not interrupted */ private Result result; /** * Constructor of the class * @param result Parameter to initialize the object that stores the results */ 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); } /** * Method that simulates the search operation * @throws InterruptedException Throws this exception if the Thread is interrupted */ 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); } }
Main.java
package com.dylan.thread.ch1.c10.core; import com.dylan.thread.ch1.c10.task.Result; import com.dylan.thread.ch1.c10.task.SearchTask; import java.util.concurrent.TimeUnit; public class Main { /** * Main class of the example * @param args */ public static void main(String[] args) { // Create a ThreadGroup ThreadGroup threadGroup = new ThreadGroup("Searcher"); Result result=new Result(); // Create a SeachTask and 10 Thread objects with this Runnable SearchTask searchTask=new SearchTask(result); for (int i=0; i<10; i++) { Thread thread=new Thread(threadGroup, searchTask); thread.start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } // Write information about the ThreadGroup to the console System.out.printf("Number of Threads: %d\n",threadGroup.activeCount()); System.out.printf("Information about the Thread Group\n"); threadGroup.list(); // Write information about the status of the Thread objects to the console 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()); } // Wait for the finalization of the Threadds waitFinish(threadGroup); // Interrupt all the Thread objects assigned to the ThreadGroup threadGroup.interrupt(); } /** * Method that waits for the finalization of one of the ten Thread objects * assigned to the ThreadGroup * @param threadGroup */ private static void waitFinish(ThreadGroup threadGroup) { while (threadGroup.activeCount()>9) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }
运行结果:
Thread Thread-0: Start
Thread Thread-0: 59
Thread Thread-1: Start
Thread Thread-1: 50
Thread Thread-2: Start
Thread Thread-2: 29
Thread Thread-3: Start
Thread Thread-3: 19
Thread Thread-4: Start
Thread Thread-4: 47
Thread Thread-5: Start
Thread Thread-5: 38
Thread Thread-6: Start
Thread Thread-6: 66
Thread Thread-7: Start
Thread Thread-7: 57
Thread Thread-8: Start
Thread Thread-8: 83
Thread Thread-9: Start
Thread Thread-9: 74
Number of Threads: 10
Information about the Thread Group
java.lang.ThreadGroup[name=Searcher,maxpri=10]
Thread[Thread-0,5,Searcher]
Thread[Thread-1,5,Searcher]
Thread[Thread-2,5,Searcher]
Thread[Thread-3,5,Searcher]
Thread[Thread-4,5,Searcher]
Thread[Thread-5,5,Searcher]
Thread[Thread-6,5,Searcher]
Thread[Thread-7,5,Searcher]
Thread[Thread-8,5,Searcher]
Thread[Thread-9,5,Searcher]
Thread Thread-0: TIMED_WAITING
Thread Thread-1: TIMED_WAITING
Thread Thread-2: TIMED_WAITING
Thread Thread-3: TIMED_WAITING
Thread Thread-4: TIMED_WAITING
Thread Thread-5: TIMED_WAITING
Thread Thread-6: TIMED_WAITING
Thread Thread-7: TIMED_WAITING
Thread Thread-8: TIMED_WAITING
Thread Thread-9: TIMED_WAITING
Thread Thread-3: End
Thread Thread-1: Interrupted
Thread Thread-8: Interrupted
Thread Thread-9: Interrupted
Thread Thread-0: Interrupted
Thread Thread-7: Interrupted
Thread Thread-6: Interrupted
Thread Thread-4: Interrupted
Thread Thread-2: Interrupted
Thread Thread-5: Interrupted