欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

由浅入深Java线程之ThreadGroup

程序员文章站 2022-05-01 14:05:07
...
  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的方法。