Java并发API提供了一个有趣的功能,它能够把线程分组。这允许我们把一个组的线程当成一个单一的单元,对组内线程对象进行访问并操作它们。例如,对于一些执行同样任务的线程,你想控制它们,不管多少线程在运行,只需要一个单一的调用,所有这些线程的运行都会被中断。
Java提供ThreadGroup类表示一组线程。线程组可以包含线程对象,也可以包含其他的线程组对象,它是一个树形结构。
下面的示例,创建5个线程并让它们休眠一个随机时间(例如模拟一个查询),当其中一个线程查找成功的时候,我们将中断其他的4个线程。
package concurrency;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class Main5 {
public static void main(String[] args) {
//创建一个标识为Searcher的线程组对象
ThreadGroup threadGroup = new ThreadGroup("Searcher");
Result result = new Result();
SearchTask searchTask = new SearchTask(result);
for(int i=0;i<5;i++){
//每一个参数是ThreadGroup对象,第二个参数是searchTask对象
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("Infomation about the Thread Group\n");
//通过list()方法打印线程组对象的信息
threadGroup.list();
//activeCount()方法获取线程组包含的线程数目
Thread[] threads = new Thread[threadGroup.activeCount()];
//通过enumerate()方法获取线程组包含的线程列表
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);
//使用interrupt()方法中断这个组中的其余线程
threadGroup.interrupt();
}
private static void waitFinish(ThreadGroup threadGroup){
while(threadGroup.activeCount() > 4){
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Result{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class SearchTask implements Runnable{
private Result 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);
}
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);
}
}
注:list()方法会打印每个线程对象的状态。ThreadGroup类有很多方法,可以查找java-api文档。