jdk源碼筆記,備忘
1.開啓一個線程中間到底發生了什麼
class MyThread extends Thread{
public void run(){
}
public static void main(String[] args) {
MyThread t1=new MyThread();
t1.start();
}
};
1.調用父類Thread的構造函數,其中init方法比較重要
其中的線程的tid和線程的名稱都是使用的內存加鎖自增
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
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) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
threadStatus 就是上節課描述的狀態,默認是0,只能調用一次,再次調用就不是0了,所以報錯,因爲線程只能啓動一次
start0() 真正的啓動線程,是一個native方法
線程啓動完成後,jvm底層會調用我們MyThread的重新的run方法,這是一個線程的大致過程
3.假如我們調用t1.run();會發生什麼呢
會發生方法調用,因爲我們重寫了父類Thread的run方法,並且可以多次調用,如下
@Override
public void run() {
if (target != null) {
target.run();
}
}
4.MyThread extends Thread 有一個缺點,因爲java單繼承,那假如我們有一個類並且有父類,那如何辦呢?
這個時候就出現了runnable這個接口,博主認爲runnable是解決這個問題實現的,並不是用來替代Thread的
下面 就來看看runnable如何解決這個問題。
new Thread(我們自己的runnable子類).start();
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
target就是我們傳進來的子類的實例
start(),調用的是Thread的start()方法,同繼承Thread一樣
不一樣的是回調方法:回調的是Thread的run方法,
target就是我們傳進來的runnable子類,然後執行子類的run方法
@Override
public void run() {
if (target != null) {
target.run();
}
}
那假如調用 new Thread(我們自己的runnable子類).run();又會發生什麼呢
調用的就是Thread的run方法
runnable子類,然後執行子類的run方法
@Override
public void run() {
if (target != null) {
target.run();
}
}