若是把公司比喻成進程,java
那麼你和我就是用戶線程,程序員
後勤部門就是守護線程(負責給你訂水,打掃辦公環境等),ide
每一個項目組就是一個線程組,函數
程序員等級就是優先級(高級程序員 總比初級程序員容易獲取資源 機率大 但不是確定)。測試
public static void main(String[] args) { Thread t = new Thread(() -> { for (int i = 0; i < 10; i++) { try { Thread.sleep(1000); System.out.println("用戶線程"); } catch (Exception e) { e.printStackTrace(); } } }); Thread tdeamon = new Thread(() -> { for (int i = 0; i < 100; i++) { try { Thread.sleep(1000); System.out.println("守護線程"); } catch (Exception e) { e.printStackTrace(); } } }); // 設置線程爲守護線程 !!必須在start以前設置 不然會報錯 tdeamon.setDaemon(true); t.start(); tdeamon.start(); }
能夠複製執行一下看看,t結束以後,tdeamon雖然沒運行夠100次可是也就結束了this
公司都沒有研發、銷售、市場等職位了,後勤也就沒有必要留着了。spa
那new Thread() 默認是守護線程仍是用戶線程 ? 線程
答案: 不肯定,要看父線程 新new的線程 默認與父線程一致code
public class TestDeamon08 { public static void main(String[] args) { System.out.println(Thread.currentThread().isDaemon() ? "守護線程":"用戶線程"); } } // 輸出: 用戶線程
###### 2 咱們看一下main線程中新建的線程進程
public static void main(String[] args) { Thread t = new Thread(); System.out.println(t.isDaemon() ? "t=守護線程":"t=用戶線程"); } // 輸出 t=用戶線程
public static void main(String[] args) { new Thread(()->{ Thread t2 = new Thread(); System.out.println(t2.isDaemon() ? "t2= 守護線程":"t2=用戶線程"); }).start(); } 輸出: t2= 用戶線程
public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { System.out.println(Thread.currentThread().isDaemon()? "thread= 守護線程" : "thread=用戶線程"); Thread t3 = new Thread(); System.out.println(t3.isDaemon() ? "t3= 守護線程" : "t3=用戶線程"); }); thread.setDaemon(true); thread.start(); Thread.sleep(10000); } // 輸出: thread= 守護線程 t3= 守護線程
// 建立線程 Thread thread = new Thread(); // 構造函數 默認名字:Thread-xxx // 調用init public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } // 下邊說的線程組ThreadGroup private void init(ThreadGroup g, Runnable target, String name, long stackSize) { init(g, target, name, stackSize, null, true); } // 主要邏輯 private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) { // 線程名字爲null 拋異常楊 if (name == null) { throw new NullPointerException("name cannot be null"); } // 設置線程名稱 this.name = name; // 獲取父線程 Thread parent = currentThread(); // SecurityManager security = System.getSecurityManager(); // 若是線程分組是null 初始化group // 若是security != null security.getThreadGroup() // 若是security == null 就獲取父線程的getThreadGroup() if (g == null) { if (security != null) { g = security.getThreadGroup(); } if (g == null) { g = parent.getThreadGroup(); } } // 一堆代碼... // 設置分組 this.group = g; // 設置daemon爲父daemon !!! this.daemon = parent.isDaemon(); // 設置優先級爲父優先級 this.priority = parent.getPriority(); // 一堆代碼... }
在上邊代碼中咱們看到,線程的默認分組是經過security獲取的,若是security爲null就是用父線程的分組。
public static void main(String[] args) throws InterruptedException { System.out.println("main線程組:"+ Thread.currentThread().getThreadGroup().getName()); } 輸出: main線程組:main
public static void main(String[] args) { new Thread(()->{ System.out.println("線程組:"+Thread.currentThread().getThreadGroup().getName()); }).start(); } // 輸出: 線程組:main
public static void main(String[] args) { ThreadGroup t = new ThreadGroup("分組01"); Thread thread = new Thread(t,()->{ System.out.println("線程組:"+ Thread.currentThread().getThreadGroup().getName()); }); thread.start(); } // 輸出: 線程組:分組01
public static void main(String[] args) { ThreadGroup t = new ThreadGroup("分組01"); Thread thread = new Thread(t,()->{ new Thread(()->{ System.out.println("線程組:"+ Thread.currentThread().getThreadGroup().getName()); }).start(); }); thread.start(); } // 輸出: 線程組:分組01
首先 他們表示線程所屬 , 好比你操做一個線程的時候,若是他是main線程組的你就過濾掉
期次線程組提供了一些方法來批量操做線程:
public static void main(String[] args) { ThreadGroup g = new ThreadGroup("分組01"); Thread thread1= new Thread(g,()->{ try { Thread.sleep(100000); } catch (Exception e) { System.out.println("線程1異常 結束:"+e.getMessage()); } }); Thread thread2= new Thread(g,()->{ try { Thread.sleep(100000); } catch (Exception e) { System.out.println("線程2異常 結束:"+e.getMessage()); } }); thread1.start(); thread2.start(); // 中止全部線程 // g.stop(); // 終端全部線程 // g.interrupt(); // 還處於活動狀態的線程總數 //System.out.println( g.activeCount()); // 輸出線程組包含線程信息 //g.list(); // 獲取線程組全部線程的最大優先級 //int max = g.getMaxPriority(); // 還有一些其餘的 讀者闊以本身去看看 瞭解爲主 }
在」一「中咱們看源碼的時候看到了,優先級默認是獲取的父線程的優先級 ,
那main線程優先級是多少呢
public static void main(String[] args) { int pro = Thread.currentThread().getPriority(); System.out.println(pro); } // 輸出結果: 5
最大優先級和最小優先級呢 ?
Thread t = new Thread(); t.setPriority(10); // 看一下setPriority的時候 限制就好了 public final void setPriority(int newPriority) { ThreadGroup g; checkAccess(); // 主要看這句 若是大於MAX_PRIORITY 或者 小於MIN_PRIORITY 就拋異常 // 那最大是MAX_PRIORITY 嘍 最小是MIN_PRIORITY 嘍 if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } if((g = getThreadGroup()) != null) { if (newPriority > g.getMaxPriority()) { newPriority = g.getMaxPriority(); } setPriority0(priority = newPriority); } } // 揭曉答案 /** * 最小優先級 */ public final static int MIN_PRIORITY = 1; /** * 默認優先級 */ public final static int NORM_PRIORITY = 5; /** * 最大優先級 */ public final static int MAX_PRIORITY = 10;
優先級有什麼用呢? 上邊說了
線程優先級高了獲取cpu的機率高
可是不必定確定比低優先級的線程先獲取到cpu 只是機率高
下邊有一個例子測試優先級獲取cpu的機率
public class ProTest02 { public static void main(String[] args) throws InterruptedException { ThreadGroup g = new ThreadGroup("測試分組"); // 4個線程 優先級:1 3 5 7 for (int i = 0; i < 4; i++) { String str = String.valueOf("優先級爲"+(2*i+1)+"的線程"); new TP(str,g,2*i+1).start(); } Thread.sleep(3000); g.interrupt(); } } class TP extends Thread{ AtomicInteger a = new AtomicInteger(); public TP(String name,ThreadGroup tg,int pro){ super(tg,name); this.setPriority(pro); } @Override public void run() { while (true){ try { Thread.sleep(1); a.incrementAndGet(); }catch (Exception e){ System.out.println(Thread.currentThread().getName()+"累加:"+a.get()); break; } } } } // 輸出結果 (不定) 優先級爲5的線程累加:2140 優先級爲7的線程累加:2294 優先級爲3的線程累加:431 優先級爲1的線程累加:139
有問題能夠留言哦,或公衆號留言(回覆快):