成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

什么是線程組?你學會了嗎?

開發 前端
線程組的出現更多的是便于有組織的管理線程,比如 Java 的線程池就用到了線程組,更多的線程知識,我們在后續的文章中會進行介紹。

一、簡介

在之前的多線程系列文章中,我們陸陸續續的介紹了Thread線程類相關的知識和用法,其實在Thread類上還有一層ThreadGroup類,也就是線程組。

今天我們就一起來簡單的聊聊線程組相關的知識和用法。

二、什么是線程組

線程組,簡單來說就是多個線程的集合,它的出現主要是為了更方便的管理線程。

從結構角度看,線程組與線程之間其實是一個父子結構,一個線程組可以擁有幾個線程,同時也可以擁有幾個線程組。整個組織結構像一棵樹一樣,每個線程一定有一個線程組,線程組可能又有一個父線程組,追溯到根節點就是一個系統線程組。

線程組與線程之間的關系,可以用如下圖來描述。

圖片圖片

比如,我們通常創建的main方法,對應的是main線程,它所屬的是main線程組,main線程組的父級是是system系統線程組。

public static void main(String[] args) {
    Thread currentThread = Thread.currentThread();
    ThreadGroup currentThreadGroup = currentThread.getThreadGroup();
    ThreadGroup systemThreadGroup = currentThreadGroup.getParent();
    System.out.println("currentThread:" + currentThread.getName());
    System.out.println("currentThreadGroup:" + currentThreadGroup.getName());
    System.out.println("systemThreadGroup:" + systemThreadGroup.getName());
}

輸出結果如下:

currentThread:main
currentThreadGroup:main
systemThreadGroup:system

其中system線程組就是根節點,再上一層就沒有了,如果調用會拋空指針異常。

線程組最主要的作用是:可以實現批量管理線程或者線程組,有效的對線程或者線程組對象進行檢查、嘗試中斷等操作。

下面我們就一起來看看ThreadGroup的常用方法和使用技巧。

三、線程組用法詳解

3.1、構造方法介紹

ThreadGroup提供了兩個構造方法,內容如下:

方法

描述

ThreadGroup(String name)

根據線程組名稱創建線程組,其父線程組為main線程組

ThreadGroup(ThreadGroup parent, String name)

根據線程組名稱創建線程組,其父線程組為指定的 parent 線程組

其中支持指定父級線程組的方法,在實際的使用中比較常見。

下面,我們演示一下這兩個構造函數的用法:

public static void main(String[] args) {
    ThreadGroup subThreadGroup1 = new ThreadGroup("sub1");
    ThreadGroup subThreadGroup2 = new ThreadGroup(subThreadGroup1, "sub2");
    System.out.println("sub1 parent thread group name:" + subThreadGroup1.getParent().getName());
    System.out.println("sub2 parent thread group name:" + subThreadGroup2.getParent().getName());
}

輸出結果如下:

sub1 parent thread group name:main
sub2 parent thread group name:sub1

3.2、核心方法介紹

ThreadGroup提供了很多有用的方法,下面整理了一些方法的簡要介紹,內容如下:

方法

描述

public final String getName()

返回此線程組的名稱

public final ThreadGroup getParent()

返回此線程組的父級

public final boolean parentOf(ThreadGroup g)

測試此線程組是線程組參數還是其父級線程組之一

public int activeCount()

返回此線程組及其子組中活動線程的數量的估計值,遞歸遍歷該線程組中所有的子組,此方法主要用于調試和監視目的

public int activeGroupCount ()

返回此線程組及其子組中活動組的數目的估計值。遞歸遍歷該線程組中的所有子群,此方法主要用于調試和監視目的

public final void checkAccess()

確定當前運行的線程是否具有修改此線程組的權限

public int enumerate(Thread[] list)

將這個線程組復制到它所在的組及其子組中

public final void destroy()

銷毀此線程組及其所有子組,當線程組還要子線程或者子線程組,會拋異常

public boolean isDestroyed()

測試此線程組是否已被銷毀

public final int getMaxPriority()

返回此線程組的最大優先級

public final void setMaxPriority(int pri)

設置組的最大優先級。線程組中具有較高優先級的線程不會受到影響

public final boolean isDaemon()

測試此線程組是否是守護線程組

public final void setDaemon(boolean daemon)

修改此線程組的守護進程狀態

public final void interrupt()

嘗試中斷此線程組中的所有線程

public void list()

將此線程組的信息打印到標準輸出。此方法僅用于調試

下面我們抽取幾個比較常見的方法,進行演示介紹。

3.2.1、activeCount 方法

activeCount()方法用于返回此線程組及其子組中活動線程的數量的估計值,因為線程的數量是動態發生變化的,返回的值只是一個估計值。

我們看一個簡單的例子就知道了。

public class MyThread extends Thread{

    public MyThread(ThreadGroup group, String name) {
        super(group, name);
    }

    @Override
    public void run() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class MyThreadMainTest {

    public static void main(String[] args) throws Exception {
        ThreadGroup tg = new ThreadGroup("group1");
        MyThread t1 = new MyThread (tg, "t1");
        MyThread t2 = new MyThread (tg, "t2");
        t1.start();
        t2.start();

        System.out.println("線程組的名稱:" +  tg.getName() + ",活動的線程數:" +  tg.activeCount());
        Thread.sleep(1000);
        System.out.println("線程組的名稱:" +  tg.getName() + ",活動的線程數:" +  tg.activeCount());
    }
}

輸出結果如下:

線程組的名稱:group1,活動的線程數:2
線程組的名稱:group1,活動的線程數:0

第一次檢查線程都處于運行狀態,因此活動的線程數為 2;過 1 秒之后,線程運行結束,活動的線程數為 0。

3.2.2、isDaemon 方法

setDaemon()方法用于測試此線程組是否是守護線程組。

需要注意的是:后臺線程組和后臺線程是兩個概念,后臺線程組的特性是最后一個線程執行完或最后一個線程被銷毀時,后臺線程組自動銷毀,線程組只是為了統一管理線程的一個方式,跟后臺線程有區別!

例子如下:

public class MyThread extends Thread{

    public MyThread(ThreadGroup group, String name) {
        super(group, name);
    }

    @Override
    public void run() {
        System.out.println("當前線程:" + Thread.currentThread().getName() + ",是否后臺線程:" +  Thread.currentThread().isDaemon());
        System.out.println("當前線程組:" + Thread.currentThread().getThreadGroup().getName() + ",是否后臺線程組:" +  Thread.currentThread().getThreadGroup().isDaemon());
    }
}
public class MyThreadMainTest4 {

    public static void main(String[] args) throws Exception {
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        new MyThread(mainGroup, "t1").start();

        Thread.sleep(100);

        // 設置守護線程組
        ThreadGroup tg = new ThreadGroup("group1");
        tg.setDaemon(true);
        new MyThread(tg,"t2").start();
    }
}

輸出結果如下:

當前線程:t1,是否后臺線程:false
當前線程組:main,是否后臺線程組:false
當前線程:t2,是否后臺線程:false
當前線程組:group1,是否后臺線程組:true
3.2.3、interrupt 方法

interrupt()方法用于嘗試中斷此線程組中的所有線程。如果正在運行的線程沒有進入阻塞,是無法中斷的。

例子如下:

public class MyThreadA extends Thread{

    public MyThreadA(ThreadGroup group, String name) {
        super(group, name);
    }

    @Override
    public void run() {
        System.out.println("線程:" + Thread.currentThread().getName() + ",開始運行");
        String t;
        for (int i = 0; i < 1000000000; i++) {
            t = i + "";
        }
        System.out.println("線程:" + Thread.currentThread().getName() + ",停止運行");
    }
}
public class MyThreadB extends Thread{

    public MyThreadB(ThreadGroup group, String name) {
        super(group, name);
    }

    @Override
    public void run() {
        System.out.println("線程:" + Thread.currentThread().getName() + ",開始運行");
        while (!Thread.interrupted()){
        }
        System.out.println("線程:" + Thread.currentThread().getName() + ",停止運行");
    }
}
public class MyThreadC extends Thread{

    public MyThreadC(ThreadGroup group, String name) {
        super(group, name);
    }

    @Override
    public void run() {
        System.out.println("線程:" + Thread.currentThread().getName() + ",開始運行");
        try {
            Thread.sleep(1000);
        } catch (Exception e){
//            e.printStackTrace();
        }
        System.out.println("線程:" + Thread.currentThread().getName() + ",停止運行");
    }
}
public class MyThreadMainTest {

    public static void main(String[] args) throws Exception {
        ThreadGroup tg = new ThreadGroup("group1");
        new MyThreadA(tg,"t1").start();
        new MyThreadB(tg,"t2").start();
        new MyThreadC(tg,"t3").start();

        // 嘗試中斷線程組里面的線程
        tg.interrupt();
    }
}

輸出結果如下:

線程:t1,開始運行
線程:t2,開始運行
線程:t2,停止運行
線程:t3,開始運行
線程:t3,停止運行

線程t1只有等它運行結束,通過interrupt()不能中斷程序!

四、小結

本文主要圍繞線程組的一些基本概念以及常用方法,并結合了一些簡單示例進行介紹。

線程組的出現更多的是便于有組織的管理線程,比如 Java 的線程池就用到了線程組,更多的線程知識,我們在后續的文章中會進行介紹。

如果有描述不對的地方,歡迎網友留言指出。

五、參考

1、https://www.cnblogs.com/xrq730/p/4856072.html

2、https://cloud.tencent.com/developer/article/1633465

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2023-01-28 09:50:17

java多線程代碼

2023-01-31 08:19:53

二進制元素數量

2024-01-19 08:25:38

死鎖Java通信

2024-02-04 00:00:00

Effect數據組件

2023-07-26 13:11:21

ChatGPT平臺工具

2023-01-10 08:43:15

定義DDD架構

2023-08-01 12:51:18

WebGPT機器學習模型

2024-01-02 12:05:26

Java并發編程

2023-01-28 10:40:56

Java虛擬機代碼

2023-03-17 16:44:44

Channel進程模型

2024-08-09 08:17:07

SSH服務器架構

2022-11-18 12:03:01

2024-11-28 10:32:32

2023-12-27 09:32:47

SQL語句數據

2023-06-15 14:10:00

kubeletCNI插件

2023-10-10 11:04:11

Rust難點內存

2024-05-06 00:00:00

InnoDBView隔離

2024-07-31 08:39:45

Git命令暫存區

2023-01-30 09:01:54

圖表指南圖形化

2024-08-06 09:47:57

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 不卡一区 | 久久久久久久久久久高潮一区二区 | 久久国产精品一区二区三区 | 最近免费日本视频在线 | 久久久国产一区二区三区 | 欧美黑人一区 | 久久精品这里 | 最近中文字幕第一页 | 色视频欧美| 成人二区三区 | 黄色在线观看网址 | 久久精品国产久精国产 | 亚洲精品在线免费观看视频 | caoporon| 围产精品久久久久久久 | 国产在线观看网站 | 国产黄色大片在线观看 | 日韩看片 | 日韩视频免费看 | 亚洲国产视频一区 | 久草在线在线精品观看 | 国产色网站| 国产成人影院 | 成人黄色在线观看 | 一区二区国产在线观看 | 色婷婷综合久久久中字幕精品久久 | 国产免费色 | 中文字幕 在线观看 | 亚洲成人午夜电影 | 日本精品一区二区三区四区 | 久久精品二区 | 国产精品一区二区无线 | 亚洲精彩免费视频 | 亚洲国产高清在线 | 成人精品国产免费网站 | h视频网站在线观看 | 自拍偷拍亚洲一区 | 久久久久久精 | 国产美女在线精品免费 | 北条麻妃一区二区三区在线观看 | 国产精品久久久久aaaa九色 |