并发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. Cloudquery的学习安装与使用

    Cloudquery的学习安装与使用 下载 官方下载地址: https://www.cloudquery.club/download https://pan.baidu.com/s/1a7XOrnMU ...

  2. [转帖]Oracle数据库下PreparedStatementCache内存问题解决方案

    https://github.com/alibaba/druid/wiki/Oracle%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8BPreparedStatementCac ...

  3. [转帖]Oracle数据库开启NUMA支持

    NUMA简介 NUMA(Non Uniform Memory Access Architecture,非统一内存访问)把一台计算机分成多个节点(node),每个节点内部拥有多个CPU,节点内部使用共有 ...

  4. [转帖]TiUP Cluster 命令合集

    https://docs.pingcap.com/zh/tidb/stable/tiup-component-cluster TiUP Cluster 是 TiUP 提供的使用 Golang 编写的集 ...

  5. [转帖]针对容器的nginx优化

    针对容器的nginx优化 本篇文章介绍了 Nginx 在容器内使用遇到的CPU核数获取问题以及对应的解决方法. 回顾上篇文章:TCP 半连接队列和全连接队列 背景 容器技术越来越普遍,很多公司已经将容 ...

  6. [转帖]部署Alertmanager

    https://flashcat.cloud/docs/content/flashcat-monitor/prometheus/alert/manager-install/ Alertmanager和 ...

  7. Windows 磁盘部分性能数据获取

    Windows 磁盘部分性能数据获取 摘要 每次晚上加班总有收获 这次发现了一个fio for windows版本的压测程序, 准备学习和使用一下. https://github.com/axboe/ ...

  8. 在K8S中,Pod创建过程包括什么?

    在Kubernetes(K8s)中,Pod的创建过程通常包括以下步骤: 提交Pod定义: 用户通过kubectl命令行工具或者调用API Server接口,提交一个包含Pod配置信息的YAML或JSO ...

  9. ClickHouse(09)ClickHouse合并树MergeTree家族表引擎之MergeTree详细解析

    目录 建表 数据存储 主键和索引在查询中的表现 主键的选择 选择与排序键不同的主键 索引和分区在查询中的应用 部分单调主键的使用 跳数索引 可用的索引类型 并发数据访问 列和表的 TTL 列TTL 表 ...

  10. 关于git的几点疑问

    git rename后查看之前的记录 对于某个文件进行rename之后,使用show log命令查看之前的修改记录都会丢失,通过命令行方式进行mv之后,在tortoisegit中查看记录还是丢失的 g ...