簡介
直奔主題,從源碼解析Thread的用法以及多線程的使用
public class Thread
extends Object
implements Runnable
// Runnable接口定
public interface Runnable {
public abstract void run();
}
//Thread重寫run方法
@Override
public void run() {
if (target != null) {
//private Runnable target;最終調Runable接口實現類的run方法
target.run();
}
}
構造方法解析
/**
*分配新的線程對象。此構造函數與Thread(null、null、gname)具有相同的效果,
*其中gname是線程名稱。自動生成的名稱的格式爲“Thread-”+n,其中n是整數。
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
o
//這裏交代可以用子類繼承Thread,即Thread t=new SonThread();並重寫Thread的run方法,調用start方法開啓線程
/**
* 分配新的線程對象。此構造函數與Thread(null、target、gname)具有相同的效果,其中
* gname是新生成的名稱。自動生成的名稱的格式爲“Thread-”+n,其中n是整數。
*
* @param target Runable接口實例
*
*/
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
//這裏交代可以用Runable接口實例作爲參數給Threa,Runable接口實例實現run方法,
從構造方法可以看出實現線程的方式只有一種,那就是new一個Threa類出來,只是run方法來源不同,一個實現Runable接口run方法,一個是重寫Thrad的run方法,但是無論如何Runable接口都是實現線程的頂層接口,除此之外表面上線程池、定時器等工具類也可以創建線程,但是底層都是通過new Thread類來實先線程,官方java語言規範明確記載new Threa()是實現線程的唯一方法。
在博客多線程編程知識點一有詳細介紹如何創建多線程
重要方法
/**
* 返回對當前正在執行的線程對象的引用。
*
* @return the currently executing thread.
*/
@FastNative
public static native Thread currentThread();
/**
* 返回當前線程的名稱
*
* @return this thread's name.
* @see #setName(String)
*/
public final String getName() {
return name;
}
通常的用法是 Thread.currentThread().getName()
/**
*
* 是線程休眠指定時間,但是不釋放鎖的控制權,時間到了甦醒繼續試圖獲取CPU執行權
*
* @param 參數爲一個毫秒值
*
* @throws IllegalArgumentException
* 如果參數爲負數
*
* @throws InterruptedException
* 如果有線程中斷了當前線程。引發此異常時,當前線程的中斷狀態將被清除。
*/
public static void sleep(long millis) throws InterruptedException {
Thread.sleep(millis, 0);
}
/**
*
*
*通常在其他線程調用此方法。來中斷線程
*
*如果此線程在調用對象類的wait()、wait(long)或wait(long,int)方法
*或該類的join()、join(long)、join(long,int)、sleep(long)或
*sleep(long,int)方法時被阻止,則其中斷狀態將被清除,並將接收到InterruptedException。
*
*
* 此外將設置中斷狀態
* 中斷不活動的線程沒有任何效果
*
* @throws SecurityException
* 自己中斷自己,如果當前線程無法修改此線程
*
* @revised 6.0
* @spec JSR-51
*/
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
nativeInterrupt();
b.interrupt(this);
return;
}
}
nativeInterrupt();
}
/**
* T測試線程是否被中斷,不會清除中斷狀態
*
*中斷返回true,否則返回false
*
* @see #interrupted()
* @revised 6.0
*/
@FastNative
public native boolean isInterrupted();
/**
*測試線程是否被中斷,並清除中斷狀態,如果被中斷返回true否則返回false,調用兩次得到結果不一樣
*
* @see #isInterrupted()
* @revised 6.0
*/
@FastNative
public static native boolean interrupted();
/**
* 在A線程中調用了B線程的join()方法時,表示只有當B線程執行完畢時,A線程才能繼續執行。
*
*
* @throws InterruptedException
* 如果任何線程中斷了當前線程。當拋出此異常時,當前線程的中斷狀態將被清除。
*/
public final void join() throws InterruptedException {
join(0);
}
/**
* 在A線程中調用了B線程的join()方法時,表示只有當B線程執行完指定的時間後,A線程才能繼續執行。
*
* <p> This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}. As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
*
* @param millis
* 等待時間
*
* @throws IllegalArgumentException
* 參數小於0
*
* @throws InterruptedException
* 如果任何線程中斷了當前線程。當拋出此異常時,當前線程的中斷狀態將被清除。
*/
public final void join(long millis) throws InterruptedException {
synchronized(lock) {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
//當參數爲0直接運行當前線程
lock.wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
//阻塞當前線程,直到時間到了
lock.wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
}
/**
* 休眠當前線程.
*
*這方法已經被啓用,因爲休眠後不釋放鎖,容易死鎖
*
*/
//過時的
@Deprecated
public final void suspend() {
throw new UnsupportedOperationException();
}
/**
* 過時方法,此方法僅用於與suspend()一起使用,喚醒一個線程,
*/
@Deprecated
public final void resume() {
throw new UnsupportedOperationException();
}
/**
*
*這個方法過時了,用來停止線程(導致線程運行一半突然停止)沒辦法完成一個基本單位的操作,同時釋放鎖,這樣導致線程不安全
*/
@Deprecated
public final void stop() {
stop(new ThreadDeath());
}
/**
*
* 使得當前線程放棄CPU執行權,讓線程從運行狀態到就緒狀態,但是不釋放鎖資源,狀態任然是可運行狀態
* 如果某一個線程是不太緊急的線程,可以在編寫時調用yield()這樣會讓其它線程得到更多的執行機會
*/
public static native void yield();
總結一下,如果要暫停線程推薦使用 interrupt()去通知目標線程是否中斷執行,而不是stop、suspend和ruseme強行中斷,詳情請看多線程核心知識(二)
Object類和線程先關的方法
/**
*使當前線程等待,直到另外一個線程調用此對象的notify()方法或notifyAll()方法喚醒去繼續獲得cpu執行
*權,或者等待指定時間重新去繼續獲得cpu執行權,調用此方法會釋放鎖資源
*
* @param millis 時間毫秒值
* @throws IllegalArgumentException 如果參數爲負數
*
* @throws IllegalMonitorStateException
* 如果當前線程不是對象監視器的所有者。
* @throws InterruptedException
* 如果被其他線程打斷報異常,而且清除中斷狀態
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
public final void wait(long millis) throws InterruptedException {
wait(millis, 0);
}
/**
* 引起當前線程等待,釋放鎖,直到另一個線程爲此對象調用notify()方法或notifyAll()方法。線程繼續設
* 法獲得執行權
*
* 此方法只能由鎖的獲得者的線程調用
*
* @throws IllegalMonitorStateException 如果當前線程不是對象監視器的所有者。
* @throws InterruptedException
* 線程被其他線程打斷拋出異常,並清除中斷狀態
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
@FastNative
public final native void wait() throws InterruptedException;
/**
* 隨機喚醒等待集中某一個線程
*
* @throws IllegalMonitorStateException 如果當前線程不是此對象監視器的所有者。
* @see java.lang.Object#notifyAll()
* @see java.lang.Object#wait()
*/
@FastNative
public final native void notify();
/**
* 喚醒等待集中所有線程
*
*
* @throws IllegalMonitorStateException 如果當前線程不是此對象監視器的所有者。
*
* @see java.lang.Object#notify()
* @see java.lang.Object#wait()
*/
@FastNative
public final native void notifyAll();