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

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

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



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

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

  1. Result.java
  1. package com.dylan.thread.ch1.c10.task;
  2. /**
  3. * Class that stores the result of the search
  4. *
  5. */
  6. public class Result {
  7. /**
  8. * Name of the Thread that finish
  9. */
  10. private String name;
  11. /**
  12. * Read the name of the Thread
  13. * @return The name of the Thread
  14. */
  15. public String getName() {
  16. return name;
  17. }
  18. /**
  19. * Write the name of the Thread
  20. * @param name The name of the Thread
  21. */
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25. }
  1. SearchTask.java
  1. package com.dylan.thread.ch1.c10.task;
  2. import java.util.Date;
  3. import java.util.Random;
  4. import java.util.concurrent.TimeUnit;
  5. /**
  6. * Class that simulates a search operation
  7. *
  8. */
  9. public class SearchTask implements Runnable {
  10. /**
  11. * Store the name of the Thread if this Thread finish and is not interrupted
  12. */
  13. private Result result;
  14. /**
  15. * Constructor of the class
  16. * @param result Parameter to initialize the object that stores the results
  17. */
  18. public SearchTask(Result result) {
  19. this.result=result;
  20. }
  21. @Override
  22. public void run() {
  23. String name=Thread.currentThread().getName();
  24. System.out.printf("Thread %s: Start\n",name);
  25. try {
  26. doTask();
  27. result.setName(name);
  28. } catch (InterruptedException e) {
  29. System.out.printf("Thread %s: Interrupted\n",name);
  30. return;
  31. }
  32. System.out.printf("Thread %s: End\n",name);
  33. }
  34. /**
  35. * Method that simulates the search operation
  36. * @throws InterruptedException Throws this exception if the Thread is interrupted
  37. */
  38. private void doTask() throws InterruptedException {
  39. Random random=new Random((new Date()).getTime());
  40. int value=(int)(random.nextDouble()*100);
  41. System.out.printf("Thread %s: %d\n",Thread.currentThread().getName(),value);
  42. TimeUnit.SECONDS.sleep(value);
  43. }
  44. }
  1. Main.java
  1.  
  1. package com.dylan.thread.ch1.c10.core;
  2. import com.dylan.thread.ch1.c10.task.Result;
  3. import com.dylan.thread.ch1.c10.task.SearchTask;
  4. import java.util.concurrent.TimeUnit;
  5. public class Main {
  6. /**
  7. * Main class of the example
  8. * @param args
  9. */
  10. public static void main(String[] args) {
  11. // Create a ThreadGroup
  12. ThreadGroup threadGroup = new ThreadGroup("Searcher");
  13. Result result=new Result();
  14. // Create a SeachTask and 10 Thread objects with this Runnable
  15. SearchTask searchTask=new SearchTask(result);
  16. for (int i=0; i<10; i++) {
  17. Thread thread=new Thread(threadGroup, searchTask);
  18. thread.start();
  19. try {
  20. TimeUnit.SECONDS.sleep(1);
  21. } catch (InterruptedException e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. // Write information about the ThreadGroup to the console
  26. System.out.printf("Number of Threads: %d\n",threadGroup.activeCount());
  27. System.out.printf("Information about the Thread Group\n");
  28. threadGroup.list();
  29. // Write information about the status of the Thread objects to the console
  30. Thread[] threads=new Thread[threadGroup.activeCount()];
  31. threadGroup.enumerate(threads);
  32. for (int i=0; i<threadGroup.activeCount(); i++) {
  33. System.out.printf("Thread %s: %s\n",threads[i].getName(),threads[i].getState());
  34. }
  35. // Wait for the finalization of the Threadds
  36. waitFinish(threadGroup);
  37. // Interrupt all the Thread objects assigned to the ThreadGroup
  38. threadGroup.interrupt();
  39. }
  40. /**
  41. * Method that waits for the finalization of one of the ten Thread objects
  42. * assigned to the ThreadGroup
  43. * @param threadGroup
  44. */
  45. private static void waitFinish(ThreadGroup threadGroup) {
  46. while (threadGroup.activeCount()>9) {
  47. try {
  48. TimeUnit.SECONDS.sleep(1);
  49. } catch (InterruptedException e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. }
  54. }

运行结果:

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. [转帖]ARM内核全解析,从ARM7,ARM9到Cortex-A7,A8,A9,A12,A15到Cortex-A53,A57

    https://www.cnblogs.com/senior-engineer/p/8668723.html 前不久ARM正式宣布推出新款ARMv8架构的Cortex-A50处理器系列产品,以此来扩大 ...

  2. [转帖]TIDB TIKV 数据是怎么写入与通过Region 分割的?

    https://cloud.tencent.com/developer/article/1882194 国产的分布式数据库不少,TDSQL, OB, TIDB ,等等都是比较知名的产品,使用的分布式协 ...

  3. [转帖]Rocksdb的优劣及应用场景分析

      研究Rocksdb已经有七个月的时间了,这期间阅读了它的大部分代码,对底层存储引擎进行了适配,同时也做了大量的测试.在正式研究之前由于对其在本地存储引擎这个江湖地位的膜拜,把它想象的很完美,深入摸 ...

  4. overflow的所有值,overlay不占位

    visible: 默认值.内容不会被修剪,会呈现在元素框之外. hidden: 内容会被修剪,并且其余内容是不可见的. scroll: 内容会被修剪,总是显示滚动条. auto: 内容被修剪,超出浏览 ...

  5. vm-storage在全部都是新metric情况下的写入性能测试

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 vm-storage中,写入索引的性能要比写入data p ...

  6. css自适应各种格式背景图

    body { position: relative; background-color: #eee; background-image: url(链接); background-size: 100%; ...

  7. 在bat中切换盘符

    在bat代码中如何在不同的盘符中切换?直接输入盘符的名字,前面不要加cd,示例 cd %~dp0 d: cd D:\Python37 e: cd E:\Code\KSFramework c: cd C ...

  8. 强化学习从基础到进阶-常见问题和面试必知必答[3]:表格型方法:Sarsa、Qlearning;蒙特卡洛策略、时序差分等以及Qlearning项目实战

    强化学习从基础到进阶-常见问题和面试必知必答[3]:表格型方法:Sarsa.Qlearning:蒙特卡洛策略.时序差分等以及Qlearning项目实战 1.核心词汇 概率函数和奖励函数:概率函数定量地 ...

  9. 驱动开发:通过SystemBuf与内核层通信

    内核层与应用层之间的数据交互是必不可少的部分,只有内核中的参数可以传递给用户数据才有意义,一般驱动多数情况下会使用SystemBuf缓冲区进行通信,也可以直接使用网络套接字实现通信,如下将简单介绍通过 ...

  10. 【文件】C语言文件操作及其使用总结篇【初学者保姆级别福利】

    [文件]C语言文件操作及其使用总结篇[初学者保姆级别福利] 一篇博客学好动态内存的管理和使用 这篇博客干货满满,建议收藏再看哦!! 求个赞求个赞求个赞求个赞 谢谢 先赞后看好习惯 打字不容易,这都是很 ...