前言
想必各位都对线程这个词不陌生,我们都知道Java中可以通过Thread、Rannable、Callable和线程池来创建一个线程。但是一个线程的创建、运行到结束到底是一个什么样的过程呢?我们以一段代码为入口点来看看Java到底是如何弄的线程。
1 2 3 4 5
| public static void main(String[] args) { new Thread(() -> { System.out.println("run..."); }).start(); }
|
源码
基本属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| private volatile String name;
private int priority;
private Thread threadQ; private long eetop;
private boolean single_step;
private boolean daemon = false;
private boolean stillborn = false;
private Runnable target;
private ThreadGroup group;
private ClassLoader contextClassLoader;
private AccessControlContext inheritedAccessControlContext;
private static int threadInitNumber;
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
private long stackSize;
private long nativeParkEventPointer;
private long tid;
private static long threadSeqNumber;
private volatile int threadStatus = 0;
volatile Object parkBlocker;
private volatile Interruptible blocker;
private final Object blockerLock = new Object();
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
|
开始到结束
静态代码块
1 2 3 4 5
| private static native void registerNatives(); static { registerNatives(); }
|
init()
主要就是初始化线程的一些基本信息(线程名、栈大小、线程组、父线程、优先级、上下文信息等)和安全检测。
注意:这里并没有将线程添加到线程组里面,只是增加线程组中未启动线程的计数。addUnstarted()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); }
private static synchronized int nextThreadNum() { return threadInitNumber++; }
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) { if (name == null) { throw new NullPointerException("name cannot be null"); }
this.name = name;
Thread parent = currentThread(); SecurityManager security = System.getSecurityManager(); if (g == null) { if (security != null) { g = security.getThreadGroup(); }
if (g == null) { g = parent.getThreadGroup(); } }
g.checkAccess(); 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 (inheritThreadLocals && parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); this.stackSize = stackSize;
tid = nextThreadID(); }
|
start()
首先会判断该线程状态是否是NEW
,是的话就将该线程添加到线程组里面(因为在init()
方法里面只是增加了计数,并未添加到线程组里面),然后调用Native方法start0()
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this);
boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } } }
public void run() { if (target != null) { target.run(); } }
|
exit()
被系统方法调用。将该线程从线程组中删除,如果线程组是守护线程组并且没有活动线程并且没有未启动的线程并且没有子线程组,就将该线程组进行销毁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
private void exit() { if (group != null) { group.threadTerminated(this); group = null; } target = null; threadLocals = null; inheritableThreadLocals = null; inheritedAccessControlContext = null; blocker = null; uncaughtExceptionHandler = null; }
void threadTerminated(Thread t) { synchronized (this) { remove(t);
if (nthreads == 0) { notifyAll(); }
if (daemon && (nthreads == 0) && (nUnstartedThreads == 0) && (ngroups == 0)) { destroy(); } } }
|
Thread状态
Thread状态的变化都是通过一些native方法进行改变的。
getState()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public State getState() { return sun.misc.VM.toThreadState(threadStatus); }
public static State toThreadState(int var0) { if ((var0 & 4) != 0) { return State.RUNNABLE; } else if ((var0 & 1024) != 0) { return State.BLOCKED; } else if ((var0 & 16) != 0) { return State.WAITING; } else if ((var0 & 32) != 0) { return State.TIMED_WAITING; } else if ((var0 & 2) != 0) { return State.TERMINATED; } else { return (var0 & 1) == 0 ? State.NEW : State.RUNNABLE; } }
|