线程分组

线程分组使得我们可以将一组线程视作单个单元,并提供了方法可以操作她们。 例如,您有某些线程在做同样的任务,您希望控制她们,不管有多少个线程还在运行、每个线程的状态如何,一个调用将打断所有线程。

Java 提供了 ThreadGroup 类。一个 ThreadGroup 对象能由 Thread 对象和其他的 ThreadGroup 对象组成,形成线程的树状结构。

任务

10个线程随机睡一段时间(如模拟搜索操作),当其中一个结束了,中断其他的。

实现

本节的示例代码在 com.elanzone.books.noteeg.chpt1.sect11 package中

  • 搜索结果类 (Result)

    • name属性: String类型,表示最早结束的线程的名称
        private String name;
    
  • 线程类 (SearchTask)

    • Result 类型的result属性及构造函数
        private Result result;
    
        public SearchTask(Result result) {
            this.result = result;
        }
    
    • 在 run 方法中调用 doTask 方法并等待它完成或捕获到 InterruptedException 异常。此方法将输出线程启动、结束或中断的信息。
            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);
    
    • doTask 方法创建一个 Random 对象生成一个随机数,然后睡眠此随机数这么多秒
        private void doTask() throws InterruptedException {
            Random random=new Random((new Date()).getTime());
            int value=(int)(random.nextDouble()*100);
            System.out.printf("Thread %s: sleep %d seconds.\n",Thread.currentThread().getName(),value);
            TimeUnit.SECONDS.sleep(value);
        }
    
  • 控制类 (Main)

    • 创建一名为 Searcher 的 ThreadGroup
        ThreadGroup threadGroup = new ThreadGroup("Searcher");
    
    • 创建 SearchTask 和 Result 对象
        Result result = new Result();
        SearchTask searchTask = new SearchTask(result);
    
    • 使用 SearchTask 对象创建10个线程。创建线程时, 第一个参数为 ThreadGroup 对象
        Thread thread = new Thread(threadGroup, searchTask);
    
    • 使用 ThreadGroup 的 list 方法输出线程组中各线程的信息
        threadGroup.list();
    
    • 使用 ThreadGroup 的 activeCount 和 enumerate 方法获知线程组中有多少个线程并得到它们的列表。
        Thread[] threads = new Thread[threadGroup.activeCount()];
        threadGroup.enumerate(threads);
    
    • 使用 interrupt 方法中断其他的线程
        threadGroup.interrupt();
    

工作原理

ThreadGroup 类保存了与之关联的 Thread 对象和其他的 ThreadGroup 对象,所以它能访问它们的所有信息(如状态)并对所有成员执行操作(如中断)。

了解更多

  • ThreadGroup 还有很多方法,请查阅 API 文档