Java天生就是多線程語言

參考網頁

https://www.cnblogs.com/yiwangzhibujian/p/6212104.htmlhtml

http://www.cnblogs.com/hvicen/p/6218981.htmljava

例子代碼

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

public class MultiThread {

    public static void main(String[] args) {
        // 獲取 Java 線程管理 MXBean
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        //不須要獲取同步的 monitor 和 synchronizer 信息,僅獲取線程和線程堆棧信息
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
        //遍歷線程信息,僅打印線程id和線程名稱信息
        for (ThreadInfo threadInfo : threadInfos) {
            System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName());
        }
    }
}

打印結果

[8] JDWP Command Reader數組

[7] JDWP Event Helper Thread多線程

[6] JDWP Transport Listener: dt_socketsocket

[5] Attach Listenerspa

[4] Signal Dispatcher線程

[3] Finalizercode

[2] Reference Handlerhtm

[1] main對象

代碼分析

ThreadMXBean類

線程管理類,經過此類能夠獲取線程信息數組。

ManagementFactory類

管理工廠類,能夠獲取線程管理類對象ThreadMXBean。

打印結果分析

從打印結果能夠看出,雖然面上只看到main線程,可是實際上Java程序中啓動了不少線程。

  1. main //main線程,用戶線程入口
  2. Reference Handler //清除Reference即引用對象的線程
  3. Finalizer //調用對象finalize方法的線程
  4. Signal Dispatcher //分發處理髮送給JVM信號的線程

以上還都是默認的系統線程,若是代碼中有用戶本身建立的Thread,那麼將會有更多的線程。

用戶主線程的入口是main()靜態方法,子線程的入口是Thread的run()方法。

★從用戶角度講開啓多線程:主線程的入口是main()靜態方法,子線程的入口是Thread的run()方法

★main方法執行後,將自動建立system線程組合main線程組,main方法所在線程存放在main線程組中

示例代碼

public class ThreadGroupDemo {
    public static void main(String[] args) {
        Thread thread1 = new Thread("my thread1") {
            public void run() {
                Object lock = new Object();
                synchronized(lock){
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        // e.printStackTrace();
                    }
                }
            }
        };
        thread1.start();

        Thread thread2 = new Thread(new ThreadGroup("my group"), "my thread2") {
            public void run() {
                Object lock = new Object();
                synchronized(lock){
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        // e.printStackTrace();
                    }
                }
            }
        };
        thread2.start();

        ThreadGroup group = Thread.currentThread().getThreadGroup();
        while (group.getParent() != null)
            group = group.getParent();
        group.list();
        thread1.interrupt();
        thread2.interrupt();
    }
}

打印結果

java.lang.ThreadGroup[name=system,maxpri=10]

    Thread[Reference Handler,10,system]

    Thread[Finalizer,8,system]

    Thread[Signal Dispatcher,9,system]

    Thread[Attach Listener,5,system]

    java.lang.ThreadGroup[name=main,maxpri=10]

        Thread[main,5,main]

        Thread[Monitor Ctrl-Break,5,main]

        Thread[my thread1,5,main]

        java.lang.ThreadGroup[name=my group,maxpri=10]

            Thread[my thread2,5,my group]

打印結果分析

其實能夠看出來,ThreadGroup是有層級關係的。main線程所在的ThreadGroup是在名爲system的ThreadGroup下面的。

線程分組ThreadGroup,是一個線程集合,同時也是一個樹節點,至關於文件夾,裏面能夠存放文件和子文件夾。

名爲main的ThreadGroup就在名爲system的ThreadGroup下面。或者能夠認爲名爲main的ThreadGroup是名爲system的ThreadGroup的【子文件夾】。同理,名爲my group的ThreadGroup能夠認爲是名爲main的ThreadGroup的【子文件夾】。

運行結果的分組與線程信息以下圖所示:

system分組就是一個根線程組,其下就是main分組,main分組就是包含主線程的分組。

線程在建立時,能夠選擇提供線程組,未提供時就會使用默認的線程組,默認線程組的提供策略由SecurityManager#getThreadGroup()決定,而默認的提供策略爲建立時當前線程所屬的線程組。

ThreadGroup#list()方法

打印出根線程組下的線程和子線程組信息。

相關文章
相關標籤/搜索