實戰(zhàn)Java高并發(fā)程序設計筆記
有關線程你必須知道的事
- 進程
- 進程(Process)是計算機中程序關于某數(shù)據(jù)集合上的一次運行活動,事系統(tǒng)進行資源分配和調(diào)度的基本單位腮鞍,是操作系統(tǒng)結(jié)構的基礎弛房。
- 線程的幾個狀態(tài)
- 首先看Thread中的一個枚舉State道盏,線程共有六個狀態(tài),每個狀態(tài)的含義注釋講的已經(jīng)很清楚了
/**
* A representation of a thread's state. A given thread may only be in one
* state at a time.
*/
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
}
-
各狀態(tài)間的關系如下圖
-
Thread的start( )方法和run( )方法的區(qū)別
- run( )方法是一個普通的方法文捶,調(diào)用該方法會在當前線程中串行執(zhí)行run( )中的代碼
- start( )是個一個線程安全的方法荷逞,該方法首先會檢查當前線程是否處于New狀態(tài), 然后將其加入到ThreadGroup中粹排,最后調(diào)用Native start0( )方法,在新的線程中串行執(zhí)行run( )中的代碼
終止線程
- 調(diào)用Thread.stop( )就會立即線程終止种远,方法太過暴力,可以強行把執(zhí)行到一半的線程終止顽耳,例如如下代碼
public class ThreadStop {
public static void main(String arg[]) throws InterruptedException {
Thread mThread = new StopThread() ;
mThread.start();
Thread.sleep(100);
mThread.stop();//調(diào)用stop終止線程可導致run( )方法中的代碼僅執(zhí)行一部分
}
static class StopThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
System.out.println("i "+ i);
}
}
}
}
可能得到如下結(jié)果坠敷,i的值并不等于99999
i 24956
i 24957
i 24958
i 24959
i 24960
i 24961
i 24962
- 線程中斷
- 線程中斷時一種重要的線程協(xié)作機制妙同。嚴格講,線程中斷并不會使線程立即退出膝迎,而是給線程發(fā)送一個通知粥帚,并告知目標線程,有人希望你退出限次!目標線接到通知后如何處理完全由目標線程自行決定芒涡。
- 中斷線程(Thread.interrupt( )),通知目標線程中斷,也就是設置中斷標志位
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();
}
- 判斷是否被中斷(Thread.isInterrupted( ))
public boolean isInterrupted() {
return isInterrupted(false);
}
/**
* Tests if some Thread has been interrupted. The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
private native boolean isInterrupted(boolean ClearInterrupted);
- 判斷是否被中斷并清除當前中斷狀態(tài)
/**
* Tests whether the current thread has been interrupted. The
* <i>interrupted status</i> of the thread is cleared by this method. In
* other words, if this method were to be called twice in succession, the
* second call would return false (unless the current thread were
* interrupted again, after the first call had cleared its interrupted
* status and before the second call had examined it).
*
* <p>A thread interruption ignored because a thread was not alive
* at the time of the interrupt will be reflected by this method
* returning false.
*
* @return <code>true</code> if the current thread has been interrupted;
* <code>false</code> otherwise.
* @see #isInterrupted()
* @revised 6.0
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
- 給出一斷代碼卖漫,顯示線程中斷,注意Thread.sleep( )方法會使當前線程休眠一段時間费尽,若在此時線程接收到中斷信號,sleep會拋出InterruptedException異常羊始,并且會清除中斷標志位依啰。若不做處理,當前線程永遠不會中斷店枣。
public class ThreadInterrupt {
public static void main(String args[]) throws InterruptedException {
Thread thread = new InterruptThread();
thread.start();
Thread.sleep(1000);
thread.interrupt();
Thread.sleep(4000);
}
static class InterruptThread extends Thread {
@Override
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Interrupted");
break;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("Interrupted when sleep");
e.printStackTrace();
Thread.currentThread().interrupt();
}
Thread.yield();//讓出當前CPU,然后跟其他線程競爭CPU的使用權
}
}
}
}
- 等待( wait )和通知( notify )
public final native void wait() throws InterruptedException;
public final native void notify();
public final native void notifyAll();
- wait 會使當前線程停止進入等待隊列而轉(zhuǎn)換為等待狀態(tài)直到其他線程在同一個object調(diào)用notify或notifyAll
- notify 會從等待隊列中隨機選擇一個線程將喚醒
- notifyAll 喚醒所有等待隊列中的線程速警,等待線程就會去競爭資源
- wait 和 sleep 都可以讓線程等待一段時間,除了wait可以被喚醒外鸯两,wait 會釋放目標對象的鎖而sleep不會釋放任何資源
- 掛起( suspend ) 和繼續(xù)執(zhí)行( resume )線程
- suspend會導致線程暫停的同時并不會釋放任何資源闷旧。如果其他任何線程想訪問被他暫用的鎖時都會那不會該所而進入等待狀態(tài)。直到對應線程調(diào)用resume被掛機的線程才能繼續(xù)執(zhí)行钧唐,但是如果resume意外地在suspend前就調(diào)用了忙灼,那么被掛起的線程可能很難有機會繼續(xù)唄執(zhí)行
- 等待線程結(jié)束( join ) 和謙讓( yield )
public final void join() throws InterruptedException
public final synchronized void join(long millis)
public static native void yield();
- join( ) 表示無限等待,它會一直阻塞當前線程钝侠,直到目標線程執(zhí)行完畢
- oin(long millis) 參數(shù)的意思是等待目標線程的最大時間该园,如果超過時間目標線程還沒有執(zhí)行完畢那么當前線程就會繼續(xù)執(zhí)行下去
- yield( )一旦調(diào)用,就會使當前線程讓出CPU帅韧,然后可能會跟其他線程競爭CPU資源