相似於計算機中,使用文件夾管理文件,也可使用線程組來管理線程,在線程組中定義一組類似的線程,在在線程組中也能夠定義子線程組。java
Thread類有幾個構造方法容許在建立線程時指定線程組,若是在建立線程時沒有指定線程組,則該線程就屬於父線程所在的線程組,JVM在建立main線程時會爲它指定一個線程組,所以每一個java線程都有一個線程組與之相關,能夠調用getThreadGroup()返回線程組嗎。sql
public class ThreadGroupText { public static void main(String[] args) { ThreadGroup threadGroup=Thread.currentThread().getThreadGroup(); System.out.println(threadGroup); } }
public class ThreadGroupText { public static void main(String[] args) { ThreadGroup threadGroup1=new ThreadGroup("group1"); System.out.println(threadGroup1); } }
public class ThreadGroupText { public static void main(String[] args) { ThreadGroup threadGroup=Thread.currentThread().getThreadGroup(); System.out.println(threadGroup); ThreadGroup threadGroup1=new ThreadGroup("group1"); System.out.println(threadGroup1.getParent()); ThreadGroup threadGroup2=new ThreadGroup(threadGroup,"group2"); System.out.println("threadGroup1-->"+threadGroup1.getParent()); System.out.println("threadGroup2-->"+threadGroup2.getParent()); } }
public class ThreadGroupText { public static void main(String[] args) { Runnable r=new Runnable() { @Override public void run() { System.out.println(Thread.currentThread()); } }; Thread t1=new Thread(r,"t1"); System.out.println(t1); } }
Thread[t1,5,main]//線程名稱 優先級 父線程組
在main線程中建立了t1線程,main爲父線程,t1爲子線程,t1沒有指定線程組t1就屬於父線程組。數組
activecount()返回當前線程組及子線程組中活動線程的數量ide
activeGroupCount()返回當前線程組以及子線程組中活動線程組的數量this
int enumerate(Thread[] list)將當前線程組中的活動線程複製到參數數組中spa
enmerate(ThreadGroup[] list) 將當前線程組中的活動線程複製到參數數組中線程
getMaxPriority()獲取線程組最大優先級,默認是10設計
getParent()返回父線程組code
getName()返回線程組的名字blog
interrup()中斷線程組的全部線程
IsDaemon()判斷當前線程組是否爲守護線程
list()將當前線程組中的活動線程打印出來
ParentOf(HtreadGroup g)判斷當前線程組是否爲參數線程組的父線程組
setDaemon()設置線程組爲守護線程
在線程Run方法中,若是有受檢異常必須捕獲處理,若是想要得到Run方法中出現的運行時異常,能夠經過回調UncaughtExceptHandler
接口得到哪一個線程出現了運行時異常。
getdefaultUncaughtExceptHandle
得到全局的UncaughtExceptHandler
getUncaughtExceptHandler
得到當前線程的UncaughtExceptHandler
setdefaultUncaughtExceptHandle
設置全局的UncaughtExceptHandler
setUncaughtExceptHandler
設置當前線程的UncaughtExceptHandler
當線程出現異常,JVM會調用Thread類的dispatchcaughtExceptHandler(Throwable e)
方法,該方法會調用
getUncaughtExceptHandler().UncaughtException(this e)
,若是想要得到異常信息,就須要設置線程的UncaughtExceptHandler
package com; public class ThreadExcept{ public static void main(String[] args) { //設置線程全局回調接口 Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){ @Override public void uncaughtException(Thread t, Throwable e) { //t參數接受發生異常的線程,e就是該線程中的異常信息 System.out.println(t.getName()+"發生了"+e.getMessage()); } }); Thread t1=new Thread(new Runnable() { @Override public void run() { String name=null; System.out.println(name.length()); } }); t1.start(); } }
在實際開發中,這種設計異常處理方式仍是比較經常使用的,尤爲是異常執行方法
若是線程產生異常,JVM會調用dispatchcaughtException
方法,該方法中調用了getUncaughtExceptionHandler().UncaughtException(this e)
;若是當前線程設置了UncaughtExceptionHandler
回調接口就直接調用它本身的UncaughtException
方法,若是沒有設置則調用當前線程所在線程組UncaughtExceptionHandler
回調接口UncaughtException
方法,若是線程組也沒有設置回調接口,則直接把異常的棧信息定向Sysytem.err中。
不少軟件包括Mysql、Zookeeper、Kafka都存在Hook線程的效驗機制,目的就是效驗進程是否已啓動,防止反覆啓動應用程序。
Hook線程也叫鉤子線程,當JVM退出的時候會執行Hook線程,常常在程序啓動的時候建立一個.lock線程,用.lock校驗程序是否在啓動,在程序退出時刪除.lock文件,在Hook線程中處理防止重複啓動以外還能夠作資源釋放,儘可能避免在Hook線程中作複雜操做。
package com; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; public class HookText { public static void main(String[] args) throws IOException, InterruptedException { //注入Hook線程,在程序退出時,刪除.lock文件 Runtime.getRuntime().addShutdownHook(new Thread(){ @Override public void run() { System.out.println("JVM退出,會啓動當前Hook線程,在Hook線程中刪除.lock文件"); getFile().toFile().delete(); } }); //檢查lock文件是否存在 if(getFile().toFile().exists()) { throw new RuntimeException("程序已啓動"); } else { getFile().toFile().createNewFile(); System.out.println("建立lock文件"); } for (int i = 0; i < 100; i++) { System.out.println("程序正在運行"); Thread.sleep(100); } } private static Path getFile() { return Paths.get("","tmp.lock"); } }
當項目已啓動,JVM會在項目文件夾目錄會自動建立一個.lock文件
只有當項目自動運行結束JVM自動退出時會刪除.lock文件,當讓程序運行時中止,.lock文件不會被刪除,再運行會拋出異常