并发API提供的一个有趣功能是可以将多个线程组成一个组。

这样我们就能将这一组线程看做一个单元并且提供改组内线程对象的读取操作。例如

你有一些线程在执行同样的任务并且你想控制他们,不考虑有多少个线程仍在运行,一个打断动作将会打断所有组内线程的执行。



Java提供了一个ThreadGroup类来表示一组线程。一个线程组对象由多个线程对象和另一个线程组对象组成,从而形成树状的线程结构。

本例中,我们将学习使用ThreadGroup对象开发一个简单例子。我们有10个线程模拟搜索(随机睡眠一段时间),并且其中一个执行结束,我们将打断其余线程。

Result.java
package com.dylan.thread.ch1.c10.task;

/**
* Class that stores the result of the search
*
*/
public class Result { /**
* Name of the Thread that finish
*/
private String name; /**
* Read the name of the Thread
* @return The name of the Thread
*/
public String getName() {
return name;
} /**
* Write the name of the Thread
* @param name The name of the Thread
*/
public void setName(String name) {
this.name = name;
} }
SearchTask.java
package com.dylan.thread.ch1.c10.task;

import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit; /**
* Class that simulates a search operation
*
*/
public class SearchTask implements Runnable { /**
* Store the name of the Thread if this Thread finish and is not interrupted
*/
private Result result; /**
* Constructor of the class
* @param result Parameter to initialize the object that stores the results
*/
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);
} /**
* Method that simulates the search operation
* @throws InterruptedException Throws this exception if the Thread is interrupted
*/
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);
} }
Main.java

package com.dylan.thread.ch1.c10.core;

import com.dylan.thread.ch1.c10.task.Result;
import com.dylan.thread.ch1.c10.task.SearchTask; import java.util.concurrent.TimeUnit; public class Main { /**
* Main class of the example
* @param args
*/
public static void main(String[] args) { // Create a ThreadGroup
ThreadGroup threadGroup = new ThreadGroup("Searcher");
Result result=new Result(); // Create a SeachTask and 10 Thread objects with this Runnable
SearchTask searchTask=new SearchTask(result);
for (int i=0; i<10; i++) {
Thread thread=new Thread(threadGroup, searchTask);
thread.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} // Write information about the ThreadGroup to the console
System.out.printf("Number of Threads: %d\n",threadGroup.activeCount());
System.out.printf("Information about the Thread Group\n");
threadGroup.list(); // Write information about the status of the Thread objects to the console
Thread[] threads=new Thread[threadGroup.activeCount()];
threadGroup.enumerate(threads);
for (int i=0; i<threadGroup.activeCount(); i++) {
System.out.printf("Thread %s: %s\n",threads[i].getName(),threads[i].getState());
} // Wait for the finalization of the Threadds
waitFinish(threadGroup); // Interrupt all the Thread objects assigned to the ThreadGroup
threadGroup.interrupt();
} /**
* Method that waits for the finalization of one of the ten Thread objects
* assigned to the ThreadGroup
* @param threadGroup
*/
private static void waitFinish(ThreadGroup threadGroup) {
while (threadGroup.activeCount()>9) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }

运行结果:

Thread Thread-0: Start
Thread Thread-0: 59
Thread Thread-1: Start
Thread Thread-1: 50
Thread Thread-2: Start
Thread Thread-2: 29
Thread Thread-3: Start
Thread Thread-3: 19
Thread Thread-4: Start
Thread Thread-4: 47
Thread Thread-5: Start
Thread Thread-5: 38
Thread Thread-6: Start
Thread Thread-6: 66
Thread Thread-7: Start
Thread Thread-7: 57
Thread Thread-8: Start
Thread Thread-8: 83
Thread Thread-9: Start
Thread Thread-9: 74
Number of Threads: 10
Information about the Thread Group
java.lang.ThreadGroup[name=Searcher,maxpri=10]
    Thread[Thread-0,5,Searcher]
    Thread[Thread-1,5,Searcher]
    Thread[Thread-2,5,Searcher]
    Thread[Thread-3,5,Searcher]
    Thread[Thread-4,5,Searcher]
    Thread[Thread-5,5,Searcher]
    Thread[Thread-6,5,Searcher]
    Thread[Thread-7,5,Searcher]
    Thread[Thread-8,5,Searcher]
    Thread[Thread-9,5,Searcher]
Thread Thread-0: TIMED_WAITING
Thread Thread-1: TIMED_WAITING
Thread Thread-2: TIMED_WAITING
Thread Thread-3: TIMED_WAITING
Thread Thread-4: TIMED_WAITING
Thread Thread-5: TIMED_WAITING
Thread Thread-6: TIMED_WAITING
Thread Thread-7: TIMED_WAITING
Thread Thread-8: TIMED_WAITING
Thread Thread-9: TIMED_WAITING
Thread Thread-3: End
Thread Thread-1: Interrupted
Thread Thread-8: Interrupted
Thread Thread-9: Interrupted
Thread Thread-0: Interrupted
Thread Thread-7: Interrupted
Thread Thread-6: Interrupted
Thread Thread-4: Interrupted
Thread Thread-2: Interrupted
Thread Thread-5: Interrupted

Java并发编程实例--10.使用线程组的更多相关文章

  1. [Java并发编程(一)] 线程池 FixedThreadPool vs CachedThreadPool ...

    [Java并发编程(一)] 线程池 FixedThreadPool vs CachedThreadPool ... 摘要 介绍 Java 并发包里的几个主要 ExecutorService . 正文 ...

  2. 2、Java并发编程:如何创建线程

    Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...

  3. 原创】Java并发编程系列2:线程概念与基础操作

    [原创]Java并发编程系列2:线程概念与基础操作 伟大的理想只有经过忘我的斗争和牺牲才能胜利实现. 本篇为[Dali王的技术博客]Java并发编程系列第二篇,讲讲有关线程的那些事儿.主要内容是如下这 ...

  4. Java并发编程:如何创建线程?

    Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...

  5. Java 并发编程——Executor框架和线程池原理

    Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...

  6. 【转】Java并发编程:如何创建线程?

    一.Java中关于应用程序和进程相关的概念 在Java中,一个应用程序对应着一个JVM实例(也有地方称为JVM进程),一般来说名字默认是java.exe或者javaw.exe(windows下可以通过 ...

  7. [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors

    [Java并发编程(二)] 线程池 FixedThreadPool.CachedThreadPool.ForkJoinPool?为后台任务选择合适的 Java executors ... 摘要 Jav ...

  8. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  9. Java并发编程 | 从进程、线程到并发问题实例解决

    计划写几篇文章讲述下Java并发编程,帮助一些初学者成体系的理解并发编程并实际使用,而不只是碎片化的了解一些Synchronized.ReentrantLock等技术点.在讲述的过程中,也想融入一些相 ...

  10. Java并发编程之深入理解线程池原理及实现

    Java线程池在实际的应用开发中十分广泛.虽然Java1.5之后在JUC包中提供了内置线程池可以拿来就用,但是这之前仍有许多老的应用和系统是需要程序员自己开发的.因此,基于线程池的需求背景.技术要求了 ...

随机推荐

  1. [转帖]Sqlserver数据库中char、varchar、nchar、nvarchar的区别及查询表结构

    https://www.cnblogs.com/liuqifeng/p/10405121.html varchar 和 nvarchar区别: varchar(n)长度为 n 个字节的可变长度且非 U ...

  2. Redis不同版本,内存分配,硬件的性能研究

    Redis不同版本,内存分配,硬件的性能研究 前言 Konw more ! Do more ! Gain more ! 骨折之后开始减肥. 前段时间跳绳导致膝盖不舒服,现在改骑车和走路. 在有限的没人 ...

  3. [转帖]Linux文件权限除了r、w、x外还有s、t、i、a权限

    https://www.cnblogs.com/hiyang/p/15122714.html setuid 是 set user ID upon execution 再次缩写为suid setgid  ...

  4. [转帖]jmeter之使用csv文件传递参数-05篇

    csv文件格式,第一列为手机号,第二列为密码 1.右键添加一个配置元件---csv数据文件设置 2.设置csv数据提取路径 3.引用数据 4.设置线程循环运行两次,然后发送请求 看到结果就执行了两次, ...

  5. [转帖]JMETER结果分析

    https://www.cnblogs.com/a00ium/p/10462892.html 我相信你同意:有很多方法可以收集和解释JMeter结果,你会感到迷茫. 嗯,看完这篇文章后,您将了解收集和 ...

  6. 【转帖】一文解析ethtool 命令的使用

    命令简介 ethtool命令用于查询和控制网络设备驱动程序和硬件设置,尤其是有线以太网设备,devname网卡的名称.网卡就像是交换机的一个端口,正常使用我们只是配置网卡IP地址等信息,网卡的速率.双 ...

  7. 【转帖】Ethernet 与 Infiniband的网络特性对比

    一.两者定位 以太网(Ethernet): 应用最广泛,是最成熟的网络互联技术,也是整个互联网络大厦的基石,兼容性非常好,可实现不同的系统之间的互连互通 IB(Infiniband): 领域很专,作为 ...

  8. [转帖]linux系统目录结构介绍

    linux的目录结构 Linux系统各个目录的作用 /: 根目录.有且只有一个根目录.所有的东西都是从根目录开始.举个例子:当你在终端里输入"/home",你其实是在告诉服务器,先 ...

  9. sass中使用穿透属性(deep)修改第三方组件样似

    <el-form-item> <el-button class="save-btn" type="primary" @click=" ...

  10. 使用Visual Studio调试 .NET源代码

    前言 在我们日常开发过程中常常会使用到很多其他封装好的第三方类库(NuGet依赖项)或者是.NET框架中自带的库.如果可以设置断点并在NuGet依赖项或框架本身上使用调试器的所有功能,那么我们的源码调 ...