自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java并發(fā)編程:什么是線程組?它有什么作用?

開發(fā) 前端
線程組是一個樹形結(jié)構(gòu),每個線程組下可以有多個線程或多個線程組。線程組可以用于統(tǒng)一控制線程的優(yōu)先級、檢查線程的權(quán)限等。?

線程組簡介

在 Java 中,ThreadGroup用于表示一個線程組。我們可以使用ThreadGroup來批量控制線程,更方便地管理線程。

ThreadGroup和Thread之間的關(guān)系非常簡單,就像它們的字面意思一樣:每個Thread必然存在于一個ThreadGroup中,一個Thread不能獨立于ThreadGroup存在。

執(zhí)行main()方法的線程名字是main,如果你在執(zhí)行new Thread()時沒有顯式指定一個ThreadGroup,那么默認(rèn)會將父線程(當(dāng)前正在執(zhí)行new Thread()的線程)的ThreadGroup設(shè)置為子線程的ThreadGroup。

示例代碼:

public class Demo {
    public static void main(String[] args) {
        Thread subThread = new Thread(() -> {
            System.out.println("子線程所在的線程組名稱是:" + 
            Thread.currentThread().getThreadGroup().getName());
            System.out.println("當(dāng)前線程(子線程)的名稱是:" + 
            Thread.currentThread().getName());
        });
        subThread.start();
        System.out.println("執(zhí)行 main() 方法的線程所在的線程組名稱是:"
        + Thread.currentThread().getThreadGroup().getName());
        System.out.println("當(dāng)前線程的名稱是:"
        + Thread.currentThread().getName());
    }
}

輸出:

執(zhí)行main()方法的線程所在的線程組名稱是: main
當(dāng)前線程的名稱是: main
子線程所在的線程組名稱是: main
當(dāng)前線程(子線程)的名稱是: Thread-0

線程組是父子結(jié)構(gòu)的,一個線程組可以包含其他線程組,也可以有其他子線程組。從結(jié)構(gòu)上看,線程組是一個樹形結(jié)構(gòu),每個線程屬于一個線程組,而該線程組又有一個父線程組,依此類推,最終可以追溯到根線程組,即System線程組。

結(jié)構(gòu)如下所示:

圖片圖片

  1. JVM 創(chuàng)建的system線程組是一組用于處理 JVM 系統(tǒng)任務(wù)的線程,比如對象銷毀、垃圾回收(GC)等。
  2. system線程組的直接子線程組是main線程組,它至少包含一個執(zhí)行main方法的main線程。
  3. main線程組的子線程組是由應(yīng)用程序創(chuàng)建的線程組。

你可以在main方法中看到 JVM 創(chuàng)建的system線程組和main線程組:

public static void main(String[] args) {
    ThreadGroup mainThreadGroup = Thread.currentThread().getThreadGroup();
    ThreadGroup systemThreadGroup = mainThreadGroup.getParent();
    System.out.println("當(dāng)前線程所在的線程組的父線程組名稱 = " + systemThreadGroup.getName());
    System.out.println("當(dāng)前線程所在的線程組名稱 = " + mainThreadGroup.getName());
}

輸出:

當(dāng)前線程所在的線程組的父線程組名稱 = system
當(dāng)前線程所在的線程組名稱 = main

一個線程可以訪問它所屬線程組的信息,但不能訪問它所屬線程組的父線程組或其他線程組的信息。

線程組的結(jié)構(gòu)

首先,我們來看一下ThreadGroup源碼中的成員變量。

public class ThreadGroup implements Thread.UncaughtExceptionHandler {
    private final ThreadGroup parent; // 父線程組
    String name;
    int maxPriority;
    boolean destroyed;
    boolean daemon;
    boolean vmAllowSuspension;
    int nUnstartedThreads = 0;
    int nthreads; // 子線程數(shù)量
    Thread threads[]; // 子線程數(shù)組
    int ngroups; // 子線程組數(shù)量
    ThreadGroup groups[]; // 子線程組數(shù)組
}

接下來,我們看一下java.lang.ThreadGroup提供的兩個構(gòu)造函數(shù),我添加了一些注釋以便理解。

// 當(dāng) JVM 啟動時,調(diào)用此構(gòu)造函數(shù)創(chuàng)建根線程組。
private ThreadGroup() {
    this.name = "system";
    this.maxPriority = Thread.MAX_PRIORITY;
    this.parent = null;
}

// 默認(rèn)情況下,傳入當(dāng)前 ThreadGroup 作為父 ThreadGroup。新線程組的父線程組是當(dāng)前運行線程的線程組。
public ThreadGroup(String name) {
    this(Thread.currentThread().getThreadGroup(), name);
}

// 傳入名稱創(chuàng)建線程組,父線程組由客戶端指定。
public ThreadGroup(ThreadGroup parent, String name) {
    this(checkParentAccess(parent), parent, name);
}

// 主要的私有構(gòu)造函數(shù),大多數(shù)參數(shù)從父線程組繼承
private ThreadGroup(Void unused, ThreadGroup parent, String name) {
    this.name = name;
    this.maxPriority = parent.maxPriority;
    this.daemon = parent.daemon;
    this.vmAllowSuspension = parent.vmAllowSuspension;
    this.parent = parent;
    parent.add(this);
}

checkParentAccess()方法用于判斷當(dāng)前運行的線程是否有權(quán)限修改線程組。

以下代碼演示了這兩個構(gòu)造函數(shù)的用法:

public class ConstructDemo {
    public static void main(String[] args) {
        ThreadGroup subThreadGroup1 = new ThreadGroup("subThreadGroup1");
        ThreadGroup subThreadGroup2 = new ThreadGroup(subThreadGroup1, "subThreadGroup2");
        System.out.println("subThreadGroup1 的父線程組名稱是:" +
        subThreadGroup1.getParent().getName());
        System.out.println("subThreadGroup2 的父線程組名稱是:" +
        subThreadGroup2.getParent().getName());
    }
}

輸出:

subThreadGroup1的父線程組名稱是: main
subThreadGroup2的父線程組名稱是: subThreadGroup1

ThreadGroup 包含的方法

ThreadGroup提供了許多有用的方法,下面簡要介紹其中一些。

方法

描述

void checkAccess()

判斷當(dāng)前運行的線程是否有權(quán)限修改線程組。

int activeCount()

返回線程組及其子組中活動線程的估計數(shù)量。

int activeGroupCount()

返回線程組及其子組中活動線程組的估計數(shù)量。

void destroy()

銷毀線程組及其所有子組。

int enumerate(Thread[] list)

將線程組及其子組中的所有活動線程復(fù)制到指定的數(shù)組中。

int getMaxPriority()

返回線程組的最大優(yōu)先級。

String getName()

返回線程組的名稱。

ThreadGroup getParent()

返回線程組的父線程組。

void interrupt()

中斷線程組中的所有線程。

boolean isDaemon()

判斷線程組是否是守護(hù)線程組。

void setDaemon(boolean daemon)

設(shè)置線程組的守護(hù)狀態(tài)。

boolean isDestroyed()

判斷線程組是否已被銷毀。

void list()

將線程組的信息打印到標(biāo)準(zhǔn)輸出。

boolean parentOf(ThreadGroup g)

判斷線程組是否是參數(shù)線程組或其祖先線程組。

void suspend()

掛起線程組中的所有線程。

void resume()

恢復(fù)線程組中所有被掛起的線程。

void setMaxPriority(int prt)

設(shè)置線程組的最大優(yōu)先級。

void stop()

停止線程組中的所有線程。

String toString()

返回線程組的字符串表示。

我們選擇其中一些方法來演示用法。

public class ThreadGroupMethodCase {
    public static void main(String[] args) throws InterruptedException {
        ThreadGroup subgroup1 = new ThreadGroup("subgroup1");
        Thread t1 = new Thread(subgroup1, "t1 in subgroup1");
        Thread t2 = new Thread(subgroup1, "t2 in subgroup1");
        Thread t3 = new Thread(subgroup1, "t3 in subgroup1");
        t1.start();
        Thread.sleep(50);
        t2.start();
        int activeThreadCount = subgroup1.activeCount();
        System.out.println("線程組 " + subgroup1.getName() + " 中的活動線程數(shù)量:" + activeThreadCount);
        ThreadGroup subgroup2 = new ThreadGroup("subgroup2");
        Thread t4 = new Thread(subgroup2, "t4 in subgroup2");
        ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
        int activeGroupCount = currentThreadGroup.activeGroupCount();
        System.out.println("線程組 " + currentThreadGroup.getName() + " 中的活動線程組數(shù)量:" + activeGroupCount);
        System.out.println("將當(dāng)前線程組的信息打印到標(biāo)準(zhǔn)輸出:");
        currentThreadGroup.list();
    }
}

輸出:

線程組 subgroup1 中的活動線程數(shù)量: 2
線程組 main 中的活動線程組數(shù)量: 2
將當(dāng)前線程組的信息打印到標(biāo)準(zhǔn)輸出:
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    java.lang.ThreadGroup[name=subgroup1,maxpri=10]
    java.lang.ThreadGroup[name=subgroup2,maxpri=10]

這里有一個有趣的地方:當(dāng)輸出當(dāng)前線程組中的活動線程數(shù)量時,實際上并沒有計算狀態(tài)為NEW和TERMINATED的線程。所以當(dāng)輸出subgroup1.activeCount()時,實際上只有一個活動線程,即t2,因為t1已經(jīng)結(jié)束,而t3還沒有啟動。

總結(jié)

簡單來說,線程組是一個樹形結(jié)構(gòu),每個線程組下可以有多個線程或多個線程組。線程組可以用于統(tǒng)一控制線程的優(yōu)先級、檢查線程的權(quán)限等。


責(zé)任編輯:武曉燕 來源: 程序猿技術(shù)充電站
相關(guān)推薦

2025-02-03 08:23:33

2024-12-25 16:04:53

2025-02-20 10:04:35

2023-09-19 16:37:47

網(wǎng)絡(luò)

2020-11-19 07:38:57

邊緣計算

2025-02-27 09:30:00

MySQLLog Buffer數(shù)據(jù)庫

2022-02-16 22:37:00

流式SQLSQL數(shù)據(jù)庫

2022-08-03 09:00:00

安全漏洞UPnP

2022-05-30 07:34:33

三范式Java

2017-03-20 15:50:55

以太網(wǎng)網(wǎng)絡(luò)工業(yè)

2023-12-11 08:03:01

Java線程線程組

2023-12-21 21:39:44

2023-09-01 13:49:00

內(nèi)存進(jìn)程線程

2025-04-29 09:47:04

2011-12-29 13:31:15

Java

2025-02-19 00:05:18

Java并發(fā)編程

2025-02-17 00:00:25

Java并發(fā)編程

2023-01-26 19:52:30

2024-07-08 00:01:00

GPM模型調(diào)度器

2022-05-07 07:35:44

工具讀寫鎖Java
點贊
收藏

51CTO技術(shù)棧公眾號