开发者社区> 问答> 正文

[@小川游鱼][¥20]什么是线程组,为什么在Java中不推荐使用?

什么是线程组,为什么在Java中不推荐使用?

展开
收起
月下丶 2018-12-14 22:36:05 2274 0
2 条回答
写回答
取消 提交回答
  • ThreadGroup概述
    在java中为了方便线程管理出现了线程组ThreadGroup的概念,每个ThreadGroup可以同时包含多个子线程和多个子线程组,在一个进程中线程组是以树形的方式存在,通常情况下根线程组是system。system线程组下是main线程组,默认情况下第一级应用自己的线程组是通过main线程组创建出来的。

    public class ThreadGroupTest {

    public static void main(String[] args) throws InterruptedException {
        //主线程对应的线程组
        printGroupInfo(Thread.currentThread());//线程组为main父线程组为system
    
        //新建线程,系统默认的线程组
        Thread appThread = new Thread(()->{},"appThread");
        printGroupInfo(appThread);//线程组为main父线程组为system
    
        //自定义线程组
        ThreadGroup factoryGroup=new ThreadGroup("factory");
        Thread workerThread=new Thread(factoryGroup,()->{},"worker");
        printGroupInfo(workerThread);//线程组为factory,父线程组为main
    
        //设置父线程组
        ThreadGroup deviceGroup=new ThreadGroup(factoryGroup,"device");
        Thread pcThread=new Thread(deviceGroup,()->{},"pc");
        printGroupInfo(pcThread);//线程组为device,父线程组为factory
    
    }
    
    static void printGroupInfo(Thread t) {
        ThreadGroup group = t.getThreadGroup();
        System.out.println("thread " + t.getName()
                + " group name is "+ group.getName()
                + " max priority is " + group.getMaxPriority()
                + " thread count is " + group.activeCount()
                + " parent group is "+ (group.getParent()==null?null:group.getParent().getName()));
    
        ThreadGroup parent=group;
        do {
            ThreadGroup current = parent;
            parent = parent.getParent();
            if (parent == null) {
                break;
            }
            System.out.println(current.getName() +" Group's  parent group name is "+parent.getName());
    
        } while (true);
        System.out.println("--------------------------");
    }
    

    }
    ThreadGroup线程组的操作
    线程组信息的获取

    public int activeCount(); // 获得当前线程组中线程数目, 包括可运行和不可运行的
    public int activeGroupCount(); //获得当前线程组中活动的子线程组的数目
    public int enumerate(Thread list[]); //列举当前线程组中的线程
    public int enumerate(ThreadGroup list[]); //列举当前线程组中的子线程组
    public final int getMaxPriority(); //获得当前线程组中最大优先级
    public final String getName(); //获得当前线程组的名字
    public final ThreadGroup getParent(); //获得当前线程组的父线程组
    public boolean parentOf(ThreadGroup g); //判断当前线程组是否为指定线程的父线程
    public boolean isDaemon(); //判断当前线程组中是否有监护线程
    public void list(); //列出当前线程组中所有线程和子线程名
    线程组的操作

    public final void resume(); //使被挂起的当前组内的线程恢复到可运行状态
    public final void setDaemon (boolean daemon); //指定一个线程为当前线程组的监护线程
    public final void setMaxPriority(int pri); //设置当前线程组允许的最大优先级
    public final void stop();//终止当前线程组中所有线程
    public final void suspend(); //挂起当前线程组中所有线程
    public String toStrinng(); //将当前线程组转换为String类的对象
    public class ThreadGroupDemo {

    public static void main(String[] args) throws InterruptedException {
        // 创建5个线程,并入group里面进行管理
        ThreadGroup threadGroup = new ThreadGroup("threadGroupTest1");
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(threadGroup,()->{
                System.out.println("Thread Start " + Thread.currentThread().getName());
                try {
                    int value = (int)new Random((new Date()).getTime()).nextDouble()*100;
                    System.out.printf("Thread %s doTask: %d\n", Thread.currentThread().getName(),value);
                    TimeUnit.SECONDS.sleep(value);
                } catch (InterruptedException e) {
                    System.out.printf("Thread %s: Interrupted\n", Thread.currentThread().getName());
                    return;
                }
                System.out.println("Thread end " + Thread.currentThread().getName());
            });
            thread.start();
            TimeUnit.SECONDS.sleep(1);
        }
        //group信息
        System.out.printf("Number of Threads: %d\n", threadGroup.activeCount());
        System.out.printf("Information about the Thread Group\n");
        threadGroup.list();
    
        //复制group的thread信息
        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());
        }
    
        //等待结束
        while (threadGroup.activeCount() > 9) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //中断group中的线程
        threadGroup.interrupt();
    }

    }

    2019-07-17 23:21:42
    赞同 展开评论 打赏
  • 线程组就是Java线程的分组,对应与Java的ThreadGroup对象。最初的定义时,期望通过该对象统一对一组线程进行管理。

    但是,该对象出现后,有明显的缺陷:

    1. 线程组里的stop, resume, suspend方法,会直接调用thread的这三个方法,而这三个方法存在死锁的问题。因此,这些管理类方法,基本无法使用。
    2. 线程组不是线程安全的,这也使得其使用价值大大降低。
    2019-07-17 23:21:42
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载