若是把公司比喻成进程,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
有问题能够留言哦,或公众号留言(回复快):