本文來自 http://blog.csdn.net/liuxian13183/ ,引用必須注明出處!
關于線程,用很長時間了,主線程下的子線程去做一些事情,就是一個代理模式,主線程分代理權給子線程,子線程幫主線程完成一些任務。
線程的方法大部分都是使用Native使用,不允許應用層修改,是CPU排程的最基本單元。實作線程的方式有三種:使用核心線程、使用者線程和混合線程來實作,奉行先行發生的原則。
核心線程:每個生成的線程,都1:1配比一個核心線程來支援,即雙線程機制,消耗一個核心資源,類似手機中應用程序
使用者線程:普通線程,高速且低耗,建立、切換、排程等問題都需要自己處理
混合實作:降低被阻塞的風險,使用者線程與核心線程相當于M:N的關系
線程的排程方式主要有兩種:協同式和搶占式,前者簡單但不可控制,一個線程執行完通知另外一個;搶占式可以通過yield方法讓出執行時間,Java目前就采用這種,同時可以使用設定優先級的方式來提前線程執行順序,但有可能被“系統”關閉。
今天我們來看下線程的源碼,進行系統的學習。
1、首先線程有六種狀态
public enum State {
/**
* The thread has been created, but has never been started.
*/
NEW,
* The thread may be run.
RUNNABLE,
* The thread is blocked and waiting for a lock.
BLOCKED,
* The thread is waiting.
WAITING,
* The thread is waiting for a specified amount of time.
TIMED_WAITING,
* The thread has been terminated.
TERMINATED
}
NEW:剛建立還沒啟動
RUNNABLE:可以執行
BLOCKED:堵塞狀态,等待持有鎖
WAITING :處理等待狀态
TIMED_WAITING:等待一些時間
TERMINATED:終止
/**
* The maximum priority value allowed for a thread.
*/
public static final int MAX_PRIORITY = 10;
* The minimum priority value allowed for a thread.
public static final int MIN_PRIORITY = 1;
* The normal (default) priority value assigned to threads.
public static final int NORM_PRIORITY = 5;
2、分别是線程可設定的最大、最小和預設優先級,級别越高執行越靠前
* Holds the thread's ID. We simply count upwards, so
* each Thread has a unique ID.
private long id;
3、每個線程都有一個獨一無二的ID
public Thread() {
create(null, null, null, 0);
private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
Thread currentThread = Thread.currentThread();
if (group == null) {
group = currentThread.getThreadGroup();
}
if (group.isDestroyed()) {
throw new IllegalThreadStateException("Group already destroyed");
this.group = group;
synchronized (Thread.class) {
id = ++Thread.count;
if (threadName == null) {
this.name = "Thread-" + id;
} else {
this.name = threadName;
this.target = runnable;
this.stackSize = stackSize;
this.priority = currentThread.getPriority();
this.contextClassLoader = currentThread.contextClassLoader;
// Transfer over InheritableThreadLocals.
if (currentThread.inheritableValues != null) {
inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
// add ourselves to our ThreadGroup of choice
this.group.addThread(this);
4、初始化一個空的線程,獲得目前運作的線程群組,設定id,name,執行線程runnable,池大小stackSize,優先級,并加入到線程群組,這是一個無參的Thread,正常情況下應該有ThreadGroup、Runnable、threadName和stackSize這四個參數。一般threadName如果為空,則報出NullPointerException,stackSize預設為0。
* Destroys the receiver without any monitor cleanup.
*
* @deprecated Not implemented.
@Deprecated
public void destroy() {
throw new NoSuchMethodError("Thread.destroy()"); // TODO Externalize???
5、destroy方法在java7已經被抛棄。
public void interrupt() {
synchronized (interruptActions) {
for (int i = interruptActions.size() - 1; i >= 0; i--) {
interruptActions.get(i).run();
}
VMThread vmt = this.vmThread;
if (vmt != null) {
vmt.interrupt();
6、停止目前線程,如果線程處于wait、join、sleep狀态的線程,會報異常。
public final boolean isAlive() {
return (vmThread != null);
7、線程是否死掉,主要是判斷虛拟機線程有沒有死掉VMThread,當然獲得目前線程也是通過VMThread.currentThread(),以及接下下獲得目前線程處于六大狀态中的哪種。
public State getState() {
// TODO This is ugly and should be implemented better.
// Make sure we have a valid reference to an object. If native code
// deletes the reference we won't run into a null reference later.
VMThread thread = vmThread;
if (thread != null) {
// If the Thread Object became invalid or was not yet started,
// getStatus() will return -1.
int state = thread.getStatus();
if(state != -1) {
return VMThread.STATE_MAP[state];
return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW;
public final void join() throws InterruptedException {
VMThread t = vmThread;
if (t == null) {
return;
synchronized (t) {
while (isAlive()) {
t.wait();
8、join堵塞目前線程,使其處于等待狀态,因為子線程執行的時間可能比主線程執行時間還長,是以join是主線程需要在它執行完後再銷毀。當然也可以加參數join(long millis, int nanos),使其等待N秒N毫秒,如果它已經處于join方法,則報InterruptedException 。
public final void setDaemon(boolean isDaemon) {
if (hasBeenStarted) {
throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
if (vmThread == null) {
daemon = isDaemon;
9、設定為守護線程,必須的runnable執行前設定,會在有非守護線程運作的時候執行,無則程式退出。
public final void setPriority(int priority) {
if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
throw new IllegalArgumentException("Priority out of range"); // TODO Externalize?
if (priority > group.getMaxPriority()) {
priority = group.getMaxPriority();
this.priority = priority;
vmt.setPriority(priority);
10、優先級主要通過VMThread來設定的,注意最高設為10最低為1,否則報 IllegalArgumentException。
public static void sleep(long millis, int nanos) throws InterruptedException {
VMThread.sleep(millis, nanos);
11、執行sleep,如果在sleep期間被interrupt,會報InterruptedException。
* Starts the new Thread of execution. The <code>run()</code> method of
* the receiver will be called by the receiver Thread itself (and not the
* Thread calling <code>start()</code>).
* @throws IllegalThreadStateException if the Thread has been started before
* @see Thread#run
public synchronized void start() {
hasBeenStarted = true;
VMThread.create(this, stackSize);
12、線程開始執行,如果start已經執行,則報IllegalThreadStateException
public final synchronized void stop(Throwable throwable) {
throw new UnsupportedOperationException();
13、stop方法棄用
public static void yield() {
VMThread.yield();
14、給另一個準備運作的線程讓路,讓它先執行
關于join和yield的差別,更在上一節:
Java中join和yield的作用