java Thread源码分析
一、使用 java 多线程
java多线程其中两种使用方式:
1、继承 Thread 类
2、实现 Runnable 接口
1 public class ThreadTest { 2 public static void main(String[] args) { 3 Thread t1 = new MyThread("thread-0001"); 4 t1.start(); 5 MyRunnable mr = new MyRunnable(); 6 Thread t2 = new Thread(mr, "thread-0002"); 7 t2.start(); 8 } 9 private static class MyThread extends Thread{ 10 public MyThread(String name) { 11 this.setName(name); 12 } 13 @Override 14 public void run() { 15 System.out.println(this.getName()+" thread run...."); 16 } 17 } 18 private static class MyRunnable implements Runnable{ 19 @Override 20 public void run() { 21 System.out.println(Thread.currentThread().getName()+" runable run...."); 22 } 23 } 24 }
二、线程初始化
继承 Thread 和 实现 Runnable 的方式都要经过初始化Thread构造函数的方式设置相关参数的过程。
构造函数如下:
public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); } public Thread(ThreadGroup group, Runnable target) { init(group, target, "Thread-" + nextThreadNum(), 0); } public Thread(String name) { init(null, null, name, 0); } public Thread(ThreadGroup group, String name) { init(group, null, name, 0); } public Thread(Runnable target, String name) { init(null, target, name, 0); } public Thread(ThreadGroup group, Runnable target, String name) { init(group, target, name, 0); } public Thread(ThreadGroup group, Runnable target, String name, long stackSize) { init(group, target, name, stackSize); }
上述构造函数涉及的参数:
ThreadGroup group(该线程所属线程组)、Runnable targer、String name(线程名)、long stackSize(线程堆栈大小,不知道有什么作用,日后再填坑)。
最终会执行 init 函数:
1 private void init(ThreadGroup g, Runnable target, String name, 2 long stackSize, AccessControlContext acc, 3 boolean inheritThreadLocals) { 4 if (name == null) { 5 throw new NullPointerException("name cannot be null"); 6 } 7 8 // 线程名 9 this.name = name; 10 11 // 创建该线程时的线程(即父线程) 12 Thread parent = currentThread(); 13 SecurityManager security = System.getSecurityManager(); 14 // 线程组 15 if (g == null) { 16 /* Determine if it's an applet or not */ 17 18 /* If there is a security manager, ask the security manager 19 what to do. */ 20 if (security != null) { 21 g = security.getThreadGroup(); 22 } 23 24 /* If the security doesn't have a strong opinion of the matter 25 use the parent thread group. */ 26 // 没有设置线程组时,默认线程组为父线程的线程组 27 if (g == null) { 28 g = parent.getThreadGroup(); 29 } 30 } 31 32 /* checkAccess regardless of whether or not threadgroup is 33 explicitly passed in. */ 34 g.checkAccess(); 35 36 /* 37 * Do we have the required permissions? 38 */ 39 if (security != null) { 40 if (isCCLOverridden(getClass())) { 41 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); 42 } 43 } 44 45 g.addUnstarted(); 46 47 // 设置线程组 48 this.group = g; 49 // 设置 50 this.daemon = parent.isDaemon(); 51 // 设置优先级和父线程的优先级相同 52 this.priority = parent.getPriority(); 53 if (security == null || isCCLOverridden(parent.getClass())) 54 this.contextClassLoader = parent.getContextClassLoader(); 55 else 56 this.contextClassLoader = parent.contextClassLoader; 57 this.inheritedAccessControlContext = 58 acc != null ? acc : AccessController.getContext(); 59 // Runnable target 60 this.target = target; 61 setPriority(priority); 62 if (inheritThreadLocals && parent.inheritableThreadLocals != null) 63 this.inheritableThreadLocals = 64 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); 65 /* Stash the specified stack size in case the VM cares */ 66 this.stackSize = stackSize; 67 68 /* Set thread ID */ 69 // 设置线程的ID(threadSeqNumber),同步递增,每个线程都会生成一个thread ID 70 // 另外一个同步递增的ID (threadInitNumber),这个在没有显式指定线程名的时候,默认生成线程名(Thread-N)。 71 // 所以,threadSeqNumber >= threadInitNumber 72 tid = nextThreadID(); 73 }
t1.start()会调用本地方法start0()启动线程:
1 public synchronized void start() { 2 /** 3 * This method is not invoked for the main method thread or "system" 4 * group threads created/set up by the VM. Any new functionality added 5 * to this method in the future may have to also be added to the VM. 6 * 7 * A zero status value corresponds to state "NEW". 8 */ 9 if (threadStatus != 0) 10 throw new IllegalThreadStateException(); 11 12 /* Notify the group that this thread is about to be started 13 * so that it can be added to the group's list of threads 14 * and the group's unstarted count can be decremented. */ 15 // 将线程添加到线程组中 16 group.add(this); 17 18 boolean started = false; 19 try { 20 // navite修饰的方法 21 start0(); 22 started = true; 23 } finally { 24 try { 25 if (!started) { 26 // 线程启动失败,从线程组中移除线程 27 group.threadStartFailed(this); 28 } 29 } catch (Throwable ignore) { 30 /* do nothing. If start0 threw a Throwable then 31 it will be passed up the call stack */ 32 } 33 } 34 }