線程相關代碼分析->常見面試題(1、Thead類)

As always,咱們直接看jdk的代碼切入:面試

首先是最簡單的Runnable接口:ide

public interface Runnable {
    public abstract void run();
}

咱們能夠看到Runnable其實特別簡單,就是接口,裏面只有一個方法(其實public abstract根本不必,不過是否是老版本jdk須要添加卻是還不清楚)。this

咱們主要須要分析的對象是Thread類:spa

 

publicclass Thread implements Runnable {  ---thread類實現了Runnable接口,也就是須要覆蓋run方法 
    private static native void registerNatives();
    static {
        registerNatives(); ---註冊類中的本地方法--必須在全部本地方法初始化以前調用;
    }
    private char        name[];---線程的名字
    private int         priority;---線程的優先級,線程優先級在Thread類中有常量定義,1-10之間的數字,若是出現定義的優先級超過這個區間會報出IllegalArgumentException()

public final static int MIN_PRIORITY = 1;---線程的最小優先級

public final static int NORM_PRIORITY = 5;---線程的默認優先級
                        public final static int MAX_PRIORITY = 10;---線程的最大優先級
  private Thread threadQ;-----此處刪除部分定義可是無用的代碼(ps:看來jdk的代碼也有這麼多所謂的「預留」字段,後來估計就不了了之了)。
  private boolean  daemon = false;--是否後臺線程,也就是守護線程,若是有用戶線程(也就是非後臺線程)後臺線程將持續存在,直到沒有用戶線程後自動終止。
                       須要注意,若是要setDaemon(true)的話必定要在thread.start()以前進行,
沒法對於一個start以後的線程進行設置。同時,由於後臺線程在用戶線程沒有了以後會自動結束,因此儘可能不要操做一些系統資源。
  private Runnable target; ---要調用run方法的runnable對象,其實也就是當前線程了

private ThreadGroup group;---對線程進行分組管理的對象,初始化線程的時候能夠指定;
注意線程組能夠包含線程組,也就是說,是一個樹形的線程結構,能夠對於整個組的線程進行優先級設置、守護非守護設置等等。
   private ClassLoader contextClassLoader;---類加載器,能夠自定義
  private static int threadInitNumber;---匿名線程的自增的線程號
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
  ThreadLocal.ThreadLocalMap threadLocals = null;---threallocalmap 這個暫且不解釋,後續會有專門的說明,線程私有的theadLocal<T>的分析
  private long tid;---當前線程的Id

  private static long threadSeqNumber;--線程自動Id

  private static synchronized long nextThreadID() {--線程自增Id
    return ++threadSeqNumber;
  }
  private volatile int threadStatus = 0;--線程狀態 VM.class中的定義:
    public static State toThreadState(int var0) {
    return (var0 & 4) != 0?State.RUNNABLE:((var0 & 1024) != 0?State.BLOCKED:((var0 & 16) != 0?State.WAITING:((var0 & 32) != 0?State.TIMED_WAITING:((var0 & 2) != 0?State.TERMINATED:((var0 & 1) == 0?State.NEW:State.RUNNABLE)))));
    }
  目前有個專門的state的枚舉來表明線程的狀態:NEW\RUNNABLE\BLOCKED\WAITING\TIMED_WAITING\TERMINATED\ ,後續會詳細解析狀態的含義來出現的場景。

  volatile Object parkBlocker;---用於記錄當前線程被誰阻塞
  private volatile Interruptible blocker;
  private final Object blockerLock = new Object();
  public static native Thread currentThread();---返回當前執行線程的一個引用
public static native void yield();---表示當前線程願意交出cpu時間供其餘線程使用,可是其實是否交的出去並不必定。這個方法其實實際場景不多用到,可是不少面試會問到。。
public static native void sleep(long millis) throws InterruptedException;--睡眠等待,不釋放同步鎖(和wait的區別是常常問到的問題,wait釋放鎖,而且wait是Object的方法)
---接下來是一堆各式各樣重載的構造參數和init方法,再也不贅述。
public synchronized void start()--啓動,判斷狀態是不是0,不然報錯
@Override
public void run() {----重寫run
if (target != null) {
target.run();
}
}
private void exit() {----可讓線程在真正結束前有機會被回收
if (group != null) {
group.threadTerminated(this);
group = null;
}
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
---幾個deprecated的stop方法,不贅述

public void interrupt() {
if (this != Thread.currentThread())
checkAccess();

synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
---接下來還有以前上面描述的屬性的get和set方法以及目前被deprecated的suspend和resume方法;
public StackTraceElement[] getStackTrace()--得到線程的堆棧信息

 其中還有些內容沒有貼出來,感受通常面試也不會問到,同時正常狀況下也不用關心的內容。線程

相關文章
相關標籤/搜索