1、Runnable接口源碼:
1 public interface Runnable {
2 public abstract void run();
3 }
2、Thread類與Runnable接口的繼承關(guān)系 1 public class Thread implements Runnable{
2
3 }
Runnable接口僅有一個(gè)run()方法,Thread類實(shí)現(xiàn)了Runnable接口,所以,Thread類也實(shí)現(xiàn)了Runnable接口。 3、構(gòu)造函數(shù) 1 public Thread() {
2 init(null, null, "Thread-" + nextThreadNum(), 0);
3 }
1 public Thread(Runnable target) {
2 init(null, target, "Thread-" + nextThreadNum(), 0);
3 }
1 public Thread(ThreadGroup group, Runnable target) {
2 init(group, target, "Thread-" + nextThreadNum(), 0);
3 }
1 public Thread(String name) {
2 init(null, null, name, 0);
3 }
這里的第三個(gè)參數(shù)是設(shè)置線程的名稱,從下面的代碼中可以看出,生成名稱的規(guī)則是:”Thread-”加上創(chuàng)建的線程的個(gè)數(shù)(第幾個(gè))。 繼續(xù)查看init方法: 1 /**
2 * Initializes a Thread.
3 *
4 * @param g the Thread group
5 * @param target the object whose run() method gets called
6 * @param name the name of the new Thread
7 * @param stackSize the desired stack size for the new thread, or
8 * zero to indicate that this parameter is to be ignored.
9 */
//每個(gè)線程都有一個(gè)優(yōu)先級(jí),高優(yōu)先級(jí)線程的執(zhí)行優(yōu)先于低優(yōu)先級(jí)線程。每個(gè)線程都可以或不可以標(biāo)記為一個(gè)守護(hù)程序。當(dāng)某個(gè)線程中運(yùn)行的代碼創(chuàng)建一個(gè)新 47 this.daemon = parent.isDaemon();
48 this.priority = parent.getPriority();
49 this.name = name.toCharArray();
50 if (security == null || isCCLOverridden(parent.getClass()))
51 this.contextClassLoader = parent.getContextClassLoader();
52 else
53 this.contextClassLoader = parent.contextClassLoader;
54 this.inheritedAccessControlContext = AccessController.getContext();
55 this.target = target;
56 setPriority(priority);
57 if (parent.inheritableThreadLocals != null)
58 this.inheritableThreadLocals =
59 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
60 /* Stash the specified stack size in case the VM cares */
61 this.stackSize = stackSize;
62
63 /* Set thread ID */
64 tid = nextThreadID();
65 }
初始化時(shí)設(shè)置了是否為守護(hù)線程,優(yōu)先級(jí),初始化名稱。 4、Thread的start方法的實(shí)現(xiàn): 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 group.add(this);
12 start0();
13 if (stopBeforeStart) {
14 stop0(throwableFromStop);
15 }
16 }
這里主要的是start0方法;查看其實(shí)現(xiàn): 1 private native void start0();
這里使用了本地調(diào)用,通過(guò)C代碼初始化線程需要的系統(tǒng)資源??梢?jiàn),線程底層的實(shí)現(xiàn)是通過(guò)C代碼去完成的。 4、Thread的run方法的實(shí)現(xiàn) 1 public void run() {
2 if (target != null) {
3 target.run();
4 }
5 }
這里的target實(shí)際上要保存的是一個(gè)Runnable接口的實(shí)現(xiàn)的引用: 1 private Runnable target;
所以使用繼承Thread創(chuàng)建線程類時(shí),需要重寫(xiě)run方法,因?yàn)槟J(rèn)的run方法什么也不干。 而當(dāng)我們使用Runnable接口實(shí)現(xiàn)線程類時(shí),為了啟動(dòng)線程,需要先把該線程類實(shí)例初始化一個(gè)Thread,實(shí)際上就執(zhí)行了如下構(gòu)造函數(shù): 1 public Thread(Runnable target) {
2 init(null, target, "Thread-" + nextThreadNum(), 0);
3 }
即是把線程類的引用保存到target中。這樣,當(dāng)調(diào)用Thread 的run方法時(shí),target就不為空了,而是繼續(xù)調(diào)用了target的run方法,所以我們需要實(shí)現(xiàn)Runnable的run方法。這樣通過(guò) Thread的run方法就調(diào)用到了Runnable實(shí)現(xiàn)類中的run方法。 這也是Runnable接口實(shí)現(xiàn)的線程類需要這樣啟動(dòng)的原因。 |
|
|
來(lái)自: 昵稱20874412 > 《Java源碼》