这一章节我们来讨论一下优先级的特性-继承性。
1代码清单
package com.ray.deepintothread.ch01.topic_15; public class PrioritySample { public static void main(String[] args) throws InterruptedException { ThreadOne threadOne = new ThreadOne(); Thread thread = new Thread(threadOne); System.out.println("before set , priority : " + Thread.currentThread().getPriority()); Thread.currentThread().setPriority(6); System.out.println("after set , priority : " + Thread.currentThread().getPriority()); thread.start(); } } class ThreadOne implements Runnable { @Override public void run() { System.out.println("ThreadOne priority : " + Thread.currentThread().getPriority()); ThreadTwo threadTwo = new ThreadTwo(); Thread thread = new Thread(threadTwo); thread.start(); } } class ThreadTwo implements Runnable { @Override public void run() { System.out.println("ThreadTwo priority : " + Thread.currentThread().getPriority()); } }
输出:
before set , priority : 5
after set , priority : 6
ThreadOne priority : 5
ThreadTwo priority : 5
package com.ray.deepintothread.ch01.topic_15; public class PrioritySample2 { public static void main(String[] args) throws InterruptedException { System.out.println("before set , priority : " + Thread.currentThread().getPriority()); Thread.currentThread().setPriority(6); System.out.println("after set , priority : " + Thread.currentThread().getPriority()); ThreadThree threadThree = new ThreadThree(); Thread thread = new Thread(threadThree); thread.start(); } } class ThreadThree implements Runnable { @Override public void run() { System.out.println("ThreadThree priority : " + Thread.currentThread().getPriority()); ThreadFour threadFour = new ThreadFour(); Thread thread = new Thread(threadFour); thread.start(); } } class ThreadFour implements Runnable { @Override public void run() { System.out.println("ThreadFour priority : " + Thread.currentThread().getPriority()); } }
before set , priority : 5
after set , priority : 6
ThreadThree priority : 6
ThreadFour priority : 6
2.对比
对比两组代码:不同之处就是把创建线程的代码顺序调换了一下
对比两组输出:截然不同的结果
为什么?
因为线程的优先级具有继承特性
3.创建线程的源码
通过一步步debug创建线程的源码,我们可以找到下面的一个方法:
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) { if (name == null) { throw new NullPointerException("name cannot be null"); } this.name = name.toCharArray(); Thread parent = currentThread(); SecurityManager security = System.getSecurityManager(); if (g == null) { /* Determine if it's an applet or not */ /* If there is a security manager, ask the security manager what to do. */ if (security != null) { g = security.getThreadGroup(); } /* If the security doesn't have a strong opinion of the matter use the parent thread group. */ if (g == null) { g = parent.getThreadGroup(); } } /* checkAccess regardless of whether or not threadgroup is explicitly passed in. */ g.checkAccess(); /* * Do we have the required permissions? */ if (security != null) { if (isCCLOverridden(getClass())) { security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } } g.addUnstarted(); this.group = g; this.daemon = parent.isDaemon(); this.priority = parent.getPriority();//创建线程的时候,是获取父线程的优先级,然后设置到线程里面 if (security == null || isCCLOverridden(parent.getClass())) this.contextClassLoader = parent.getContextClassLoader(); else this.contextClassLoader = parent.contextClassLoader; this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext(); this.target = target; setPriority(priority);//设置线程优先级 if (parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); /* Stash the specified stack size in case the VM cares */ this.stackSize = stackSize; /* Set thread ID */ tid = nextThreadID(); }
总结:这一章节我们讨论了线程优先级的继承特性。
我的github:https://github.com/raylee2015/DeepIntoThread