本博客系列是學習併發編程過程當中的記錄總結。因爲文章比較多,寫的時間也比較散,因此我整理了個目錄貼(傳送門),方便查閱。html
併發編程系列博客傳送門java
Thread
類是Java中實現多線程編程的基礎類。本篇博客就來介紹下Thread
類的經常使用API和常見用法。編程
Thread
類經常使用的方法以下:數據結構
還有Thread
類提供了功能豐富的構造函數,你們能夠選合適的使用多線程
public class MyThread { public static void main(String[] args) { Thread thread = Thread.currentThread(); //這個方法返回的是當前線程所在線程組以及這個線程組的子線程組內活動的線程數 //這個值是一個估計值,因此這個方法的應用場景不大 int activeCount = Thread.activeCount(); System.out.println("當前系統中活動線程數["+activeCount+"]"); //向標準錯誤輸出流輸出當前的線程棧,不會阻斷程序的繼續執行 Thread.dumpStack(); //獲取全部線程棧信息 Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces(); //獲取類加載器 ClassLoader contextClassLoader = thread.getContextClassLoader(); //獲取當前線程名字 String threadName = thread.getName(); System.out.println("current thread name["+threadName+"]"); //獲取當前線程ID long threadId = thread.getId(); System.out.println("current thread id["+threadId+"]"); //獲取當前線程的優先級,一共有1~10總共10個優先級,這個優先級並非在 //全部平臺都生效的 int priority = thread.getPriority(); System.out.println("current thread priority["+priority+"]"); StackTraceElement[] stackTrace = thread.getStackTrace(); System.out.println("-------------stackTrace info--------------"); for (int i = 0; i < stackTrace.length; i++) { StackTraceElement element = stackTrace[i]; System.out.println("className:["+element.getClassName()+"]"); System.out.println("fileName:["+element.getFileName()+"]"); System.out.println("line nunber:["+element.getLineNumber()+"]"); System.out.println("method name:["+element.getMethodName()+"]"); System.out.println("is native method:["+element.isNativeMethod()+"]"); System.out.println("------------------------------------------"); } Thread.State state = thread.getState(); System.out.println("thread state:["+state+"]"); ThreadGroup threadGroup = thread.getThreadGroup(); String threadGroupName = threadGroup.getName(); System.out.println("thread group name:["+threadGroupName+"]"); //線程睡眠,調用sleep方法會使得線程進入timed_waiting狀態,若是線程已經 //得到了鎖資源,調用sleep方法是不會釋放這個鎖的 Thread.sleep(2000,500); Thread.sleep(1000); TimeUnit.SECONDS.sleep(2); Thread thread1 = new Thread(new Runnable() { @SneakyThrows @Override public void run() { TimeUnit.SECONDS.sleep(100); } }); thread1.start(); thread1.join(50); } }
守護線程能夠理解爲服務線程,他們的做用就是服務於其餘用戶線程。當系統中不存在其餘用戶線程時,這些守護線程也會自動消亡。好比JVM的垃圾清理線程就是守護線程。咱們可使用以下方法查看和設置線程是不是守護線程。併發
thread.isDaemon(); thread.setDaemon(true);
開發過程當中咱們可能會有這樣的需求:多個線程分別加載資源,等這些線程資源加載完畢以後對這些資源作統一彙總處理。join
方法就能實現相似的功能。ide
調用線程的join方法會使得調用線程進入waiting狀態,直到被調用的線程執行結束,調用線程纔會從新得到執行的機會。函數
public class MyThread { public static void main(String[] args) throws Exception { Thread thread1 = new Thread(new Runnable() { @SneakyThrows @Override public void run() { TimeUnit.SECONDS.sleep(100); } }); thread1.start(); thread1.join(); System.out.println("main thread end..."); } }
上面的代碼中,main線程調用了thread1的join方法,main線程會被掛起進入waiting狀態,直到thread1執行完畢以後,main線程纔有機會從新得到執行機會。學習
join方法還有一個重載方法,這個方法能夠指定超時時間。測試
thread1.join(50);
若是thread1線程在50ms內還沒執行完,main線程就能夠從新得到執行機會。
調用線程的yield方法是在暗示讓這個線程讓出CPU資源,若是這個線程在執行一個CPU時間,已經執行到一半了,調用yield以後這個線程會放棄剩下的一半CPU時間回到就緒狀態。可是須要注意的是線程能夠徹底忽略yield方法的調用,也就是yield方法並非每次都調用成功的:
先貼上一段網友對線程中斷的總結。
須要說明的是:interrupt()方法並非中斷線程,而是中斷阻塞狀態,或者將線程的[中斷標誌位]置爲true。中斷後線程將繼續執行。
幾個中斷方法對比: