Java并发包里面提供了ThreadGroup类可以帮助我们有效地管理线程组。让我们来看一个生动的例子. Java线程组可以有线程对象或者子线程组组成。也就是说ThreadGroup可以是产生线程树。
让我们看一个简单的例子,这个例子模仿一个搜索任务,将启动10个线程遍历获取指定目录下面的excel文件列表,一旦有一个线程完成遍历,将中断其余的9个任务。
- import java.io.File;
- import java.util.concurrent.TimeUnit;
- public class SearchTask implements Runnable {
- private String rootDir;
- private SearchResult result;
- public SearchTask(String rootDir, SearchResult result) {
- super();
- this.rootDir = rootDir;
- this.result = result;
- }
- public String getRootDir() {
- return rootDir;
- }
- public void setRootDir(String rootDir) {
- this.rootDir = rootDir;
- }
- public SearchResult getResult() {
- return result;
- }
- public void setResult(SearchResult result) {
- this.result = result;
- }
- @Override
- public void run() {
- String name = Thread.currentThread().getName();
- System.out.printf("Thread %s: Start\n",name);
- try{
- doSearch(new File(this.rootDir));
- result.setTaskName(name);
- }catch(InterruptedException e){
- System.out.printf("Thread %s: Interrupted\n",name);
- return;
- }
- System.out.printf("Thread %s: End\n",name);
- }
- private void doSearch(File root) throws InterruptedException{
- if(root != null && root.isDirectory()){
- TimeUnit.SECONDS.sleep(1);
- File[] files = root.listFiles();
- if( files != null ){
- for(File file : files){
- if(file.isFile() && file.getName().endsWith(".xls")){
- result.getFiles().add(file.getAbsolutePath());
- result.increaseCount();
- }else if(file.isDirectory()){
- doSearch(file);
- }
- }
- }
- }
- }
- }
- package com.concurrent.exercise.threadgroup;
- import java.util.ArrayList;
- import java.util.List;
- public class SearchResult {
- private int count = 0;
- private String taskName;
- private List<String> files = new ArrayList<String>();
- public String getTaskName() {
- return taskName;
- }
- public void setTaskName(String taskName) {
- this.taskName = taskName;
- }
- public void setCount(int count) {
- this.count = count;
- }
- public void setFiles(List<String> files) {
- this.files = files;
- }
- public int getCount() {
- return count;
- }
- public void increaseCount() {
- count++;
- }
- public List<String> getFiles(){
- return files;
- }
- }
- import java.util.concurrent.TimeUnit;
- public class TestThreadGroup {
- public static void main(String[] args){
- String searchDir = "D:\\";
- ThreadGroup threadGroup = new ThreadGroup("Searcher");
- for(int i = 0; i < 3; i++){
- SearchTask task = new SearchTask(searchDir,new SearchResult());
- Thread thread = new Thread(threadGroup, task);
- thread.start();
- try{
- TimeUnit.SECONDS.sleep(2);
- }catch(InterruptedException e) {
- e.printStackTrace();
- }
- }
- waitFinish(threadGroup);
- threadGroup.interrupt();
- }
- private static void waitFinish(ThreadGroup threadGroup) {
- while (threadGroup.activeCount() > 2) {
- try {
- list(threadGroup);
- TimeUnit.SECONDS.sleep(1);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- private static void list(ThreadGroup threadGroup) {
- assert(threadGroup != null);
- threadGroup.list();
- }
- }
在启动三个线程后,进入waitFinish方法,当其中一个线程结束后,waitFinish立即对出并调用ThreadGroup终止剩下的线程。
由于ThreadGroup存储了线程和子线程组对象,可以使用ThreadGroup对一组线程执行统一的操作,比如interrupt.
可以参考Java API Doc知道更多关于ThreadGroup的方法。