Java 多线程进阶-并发编程 线程组ThreadGroup

Posted Sweet小马

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 多线程进阶-并发编程 线程组ThreadGroup相关的知识,希望对你有一定的参考价值。

Java 多线程进阶-并发编程

  • 并行计算

    • 业务: 任务多, 数据量大
    • 串行 vs 并行
      • 串行编程简单, 并行编程困难
      • 单个计算核频率下降, 计算核数增多, 整体性能变高
    • 并行困难(任务分配和执行过程高度耦合)
      • 如何控制粒度, 切割任务
      • 如何分配任务给线程, 监督线程执行过程
    • 并行模式
      • 主从模式(Master - Slave): 主线程指挥从线程去工作
      • Worker模式(Worker - Worker): 又称Peer2Peer, 所有线程是平等的, 无中心化的模式.
    • Java并发编程
      • Thread/Runnable/ThreadGroup管理
      • Executor框架
      • Fork-Join框架
  • 线程组ThreadGroup

    • 线程的集合, 树形结构, 大线程组可以包括小线程组
    • 可以通过 enumerate方法 遍历组内的线程,执行操作.
    • 能有效管理多个线程, 但是管理效率低
    • 任务分配和执行过程高度耦合
    • 重复 创建线程/关闭线程 操作, 无法重用线程
      (线程组只是提供一个数组的方式来控制线程. 线程和线程组中的线程都是 new 产生出来的, start 一次后, 就不能再次 start 了. new 的代价是很昂贵的, 只运行一次, 性价比过低.)
    • 示例代码
          package thread0411;
      
          import java.time.LocalDateTime;
          import java.util.Date;
          import java.util.Random;
          import java.util.concurrent.TimeUnit;
      
          /**
           * 1. 依次启动十个线程放在一个线程组里, 每个线程随机完成若干时间的任务
           * 23. 查看线程组状态
           * 4. while检测是否十个线程都还在active状态, 如果是则阻塞.
           * 5. 终止线程组中的所有线程.
           */
          public class ThreadGroupDemo {
              public static void main(String[] args) {
                  // 创建线程组
                  ThreadGroup threadGroup = new ThreadGroup("Searcher111");
      
                  // 创建一个任务, 10个线程完成
                  System.out.println(LocalDateTime.now() + " => " + "====== 1 子线程启动 ======");
                  Result result = new Result();
                  Searcher searchTask = new Searcher(result);
                  for (int i = 0; i < 10; i++) {
                      Thread thread = new Thread(threadGroup, searchTask);
                      thread.start();
                      try {
                          TimeUnit.SECONDS.sleep(1); // 每隔1秒启动一个线程
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  System.out.println();
      
                  // 查看线程组消息
                  System.out.println(LocalDateTime.now() + " => " + "====== 2 查看线程组状态 ======");
                  System.out.printf(LocalDateTime.now() + " => " + "线程组当前 active 线程数量: %d" + "
      ", threadGroup.activeCount());
                  System.out.println(LocalDateTime.now() + " => " + "线程组消息明细");
                  threadGroup.list();
                  System.out.println("");
      
      
                  // 遍历线程组
                  System.out.println(LocalDateTime.now() + " => " + "====== 3 遍历线程组 ======");
                  Thread[] threads = new Thread[threadGroup.activeCount()];
                  threadGroup.enumerate(threads); // 将线程组中的active的线程拷贝到数组中.
                  for (int i = 0; i < threadGroup.activeCount(); i++) {
                      System.out.printf(LocalDateTime.now() + " => " + "Thread %s: state: %s " + "
      ", threads[i].getName(), threads[i].getState());
                  }
                  System.out.println("");
      
                  // 等待线程结束
                  System.out.println(LocalDateTime.now() + " => " + "====== 4 等待线程结束 ======");
                  // 循环检测是否所有线程都还在进行中...
                  while (threadGroup.activeCount() > 9) {
                      try {
                          TimeUnit.SECONDS.sleep(1);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  System.out.println("");
      
                  // 中断线程组中的所有线程
                  System.out.println(LocalDateTime.now() + " => " + "====== 5 中断线程组中的所有线程 ======");
                  threadGroup.interrupt();
      
              }
      
          }
      
          class Result {
              private String name;
      
              public String getName() {
                  return name;
              }
      
              public void setName(String name) {
                  this.name = name;
              }
          }
      
          class Searcher implements Runnable {
              private Result result;
      
              public Searcher(Result result) {
                  this.result = result;
              }
      
              @Override
              public void run() {
                  String name = Thread.currentThread().getName();
                  System.out.printf(LocalDateTime.now() + " => " + "Thread %s: 启动" + "
      ", name);
                  try {
                      doTask();
                      result.setName(name);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                      System.out.printf(LocalDateTime.now() + " => " + "Thread %s: 被中断
      ", name);
                      return;
                  }
                  System.out.printf(LocalDateTime.now() + " => " + "Thread %s 完成
      ", name);
              }
      
              // 模拟工作若干时间
              void doTask() throws InterruptedException {
                  Random random = new Random(new Date().getTime());
                  int value = (int) (random.nextDouble() * 100);
                  System.out.printf(LocalDateTime.now() + " => " + "Thread %s: %d
      ", Thread.currentThread().getName(), value);
                  TimeUnit.SECONDS.sleep(value); // 随机等待若干秒, 模拟进行工作
              }
          }
      

以上是关于Java 多线程进阶-并发编程 线程组ThreadGroup的主要内容,如果未能解决你的问题,请参考以下文章

Java并发编程从入门到精通-总纲

Java 多线程进阶-并发协作控制

进阶Java编程多线程深入话题

Java并发编程:Runnable和Thread实现多线程的区别(含代码)

Java语法进阶10-多线程

Java并发多线程编程——线程之间的通信之join()