• 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); // 随机等待若干秒, 模拟进行工作
                }
            }
        
  • 相关阅读:
    NIS server on centOS 7
    fabric-python-基于centos 7
    玩玩Jenkins
    身份认证技术性能对比
    Linux时区设置和时间同步-基于CentOS 6(最小安装)
    openldap+phpadmin的最简安装和配置
    tomcat8.5的网页管理(远程)配置、SSL证书配置-基于Debian 9
    tomcat添加为service服务-基于Debian 9
    安装、配置MySQL5.8基于Debian 9(用apt-get install 默认安装结果是mariadb)
    下载并配置jdk环境-基于debain 9
  • 原文地址:https://www.cnblogs.com/sweetXiaoma/p/12725897.html
Copyright © 2020-2023  润新知