线程管理(十)线程组

简介:

线程组

Java并发 API里有个有趣的方法是把线程分组。这个方法允许我们按线程组作为一个单位来处理。例如,你有一些线程做着同样的任务,你想控制他们,无论多少线程还在运行,他们的状态会被一个call 中断。

Java 提供 ThreadGroup 类来组织线程。 ThreadGroup 对象可以由 Thread 对象组成和由另外的 ThreadGroup 对象组成,生成线程树结构。

在这个指南中, 我们将开发一个简单的例子来学习 ThreadGroup 对象。我们有 10 个随机时间休眠的线程 (例如,模拟搜索),然后当其中一个完成,就中断其余的。

准备

指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。

怎么做呢

按照这些步骤来实现下面的例子::

1.   首先,创建一个类名为 Result。它会保存最先结束的线程的名字。声明一个 private String 属性名为 name 并提供相应的读值和设置值的方法。

2.   创建一个类名为 SearchTask a并一定实现 Runnable 接口。


1 public class SearchTask implements Runnable {

3.   声明一个Result类的 private 属性变量并实现和初始化这类属性的构造函数。


1 private Result result;
2 public SearchTask(Result result) {
3 this.result=result;
4 }

4.   实现run()方法。 它会调用doTask() 方法和等待它结束或者接收一个 InterruptedException 异常。 这方法会写信息表明开始,结束,或者线程中断。


01 @Override
02 public void run() {
03 String name=Thread.currentThread().getName();
04 System.out.printf("Thread %s: Start\n",name);
05 try {
06 doTask();
07 result.setName(name);
08 } catch (InterruptedException e) {
09 System.out.printf("Thread %s: Interrupted\n",name);
10 return;
11 }
12 System.out.printf("Thread %s: End\n",name);
13 }

5.   实现 doTask() 方法。它会创建一个 Random 对象生一个随机数字并用这个数字调用 sleep() 方法 。


1 private void doTask() throws InterruptedException {
2 Random random=new Random((new Date()).getTime());
3 int value=(int)(random.nextDouble()*100);
4 System.out.printf("Thread %s: %d\n",Thread.currentThread(). getName(),value);
5 TimeUnit.SECONDS.sleep(value);
6 }

6.   现在, 创建例子主类通过创建 Main 类和实现 main() 方法.


1 public class Main {
2 public static void main(String[] args) {

7.   首先, 创建一个 ThreadGroup 对象命名 Searcher.


1 ThreadGroup threadGroup = new ThreadGroup("Searcher");

8.   然后, 创建 一个 SearchTask 对象和 一个 Result 对象。


1 Result result=new Result();
2 SearchTask searchTask=new SearchTask(result);

9.   现在, 使用SearchTask对象创建 10个 Thread o对象。当你调用Thread 类的构造函数时,传递它作为ThreadGroup对象的第一个参数。


1 for (int i=0; i<5; i++) {
2 Thread thread=new Thread(threadGroup, searchTask);
3 thread.start();
4 try {
5 TimeUnit.SECONDS.sleep(1);
6 } catch (InterruptedException e) {
7 e.printStackTrace();
8 }
9 }

10. 使用list() 方法写关于 ThreadGroup ob对象信息。

1 System.out.printf("Number of Threads: %d\n",threadGroup. activeCount());
2 System.out.printf("Information about the Thread Group\n");
3 threadGroup.list();

11. 使用 activeCount() 和 enumerate() 方法来获取线程个数和与ThreadGroup对象关联的线程的列表。我们可以用这个方法来获取信息, 例如,每个线程状态。


1 Thread[] threads=new Thread[threadGroup.activeCount()];
2 threadGroup.enumerate(threads);
3 for (int i=0; i<threadGroup.activeCount(); i++) {
4 System.out.printf("Thread %s: %s\n",threads[i].getName(),threads[i].getState());
5 }

12. 调用 waitFinish()方法. 我们等下来实现这方法。它会等待ThreadGroup对象中的其中一个线程结束。


1 waitFinish(threadGroup);

13. 用interrupt() 方法中断组里的其他线程。


1 threadGroup.interrupt();

14. 实现 waitFinish() 方法. 它会使用 activeCount() 方法来控制到最后一个线程。


1 private static void waitFinish(ThreadGroup threadGroup) {
2 while (threadGroup.activeCount()>9) {
3 try {
4 TimeUnit.SECONDS.sleep(1);
5 } catch (InterruptedException e) {
6 e.printStackTrace();
7 }
8 }
9 }

15. 运行例子并查看结果。

它是怎么工作的

在下面的截图内, 你可以发现 list() 方法 的输出和当我们把每个线程对象的状态写入时候的输出, 请看截图:

ThreadGroup 类储存线程对象和其他有关联的 ThreadGroup 对象,所以它可以访问他们的所有信息 (例如,状态) 和全部成员的操作表现 (例如,中断)。

更多

ThreadGroup 类有很多方法. 查看 API 文档里的这些方法的详细说明。 

目录
相关文章
|
2月前
|
Java
直接拿来用:进程&进程池&线程&线程池
直接拿来用:进程&进程池&线程&线程池
|
5月前
|
Java
java线程之线程池
java线程之线程池
|
缓存 前端开发 Java
线程池中线程重用导致的问题
之前在公司做的一个项目中,有一个 core 的公共依赖包,那个依赖里面简单封装了用户的信息。
|
Java
线程和线程池
线程和线程池
108 0
线程和线程池
|
Java
Java并发之线程组ThreadGroup介绍
Java并发之线程组ThreadGroup介绍
242 0
|
Java
线程组与线程池
线程组与线程池
115 0
|
SQL 开发框架 Java
线程-线程池1
今天我们说说线程池,线程池为什么来呢?
114 0
线程-线程池1
|
数据处理 调度
进程与线程 thread (二)——线程概念
为什么线程会有用以及如何使用它们   人们需要线程的主要原因: 1、在许多应用中同时发生着多种活动。其中某些活动随着时间的推移会阻塞。
894 0
|
Java Android开发 调度
线程与线程池的应用
异步任务AsyncTask 源码 地址http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/os/AsyncTask.java 最近在Android开发上遇到线程遇到诸多问题,特此记录下。
1009 0