天天看點

《java多線程程式設計核心技術》筆記

一.java多線程基礎:熟悉Thread類

1.2實作多線程方法:

繼承Thread類

實作Runnable接口

1.4isAlive()

1.5sleep()

1.6getId()

1.7停止線程:

interrupt():把标志位設定而已,不會立即停止
 interrupted():目前線程是否中斷?狀态标志位置為false
 isInterrupted():線程是否中斷
 抛出異常(建議)
 調用處interrupt(),線程run中判斷标志位,return停止線程
           

1.8暫停線程:

suspend()

resume()

1.9讓出cpu

yield()

二.對象及變量的并發通路

2.1.synchronized同步方法:

方法變量線程安全。

多個線程通路一個對象的執行個體變量不安全。

synchronized方法為對象鎖,需要該對象鎖的都必須同步(包括synchronized(this)),不需要鎖的随時讀取,是以特别要注意髒讀。

為可重入鎖,可自己再次擷取自己内部鎖,有點像總統到期自己繼續做總統。

異常自動釋放鎖

同步不可繼承

2.2synchronized代碼塊:

synchronized(this)

synchronized(非this對象):一般不用String,而new Object()或者object作形參,鎖object.

2.3volatile

使所讀資料從記憶體直接讀取,而非線程的緩存

不具備原子性:一百個線程對volatile cnt加一,然後輸出。結果不具原子性,仍需加鎖。

AtomicInteger i++線程安全。但方法調用不具有原子性,原子類操作資料也不一定安全。

三.線程間通訊

3.1:等待/通知

wait() notify():notify()喚醒線程到就緒态,還需拿到鎖才能執行。

wait()釋放鎖,notify()不釋放鎖。

執行wait()的線程如果interupt()會抛異常

notify()随機喚醒一個線程,要喚醒全部可用notifyAll(),

wait(long)

單生産消費模型–》多生産多消費

3.2:join()

threadTest.join():等等我

threadTest.join(long):等我一會

join()+interupt():可能冒異常

join()釋放鎖,sleep()不釋放鎖

3.3ThreadLocal:

希望每個線程有自己的值,每個線程有私有資料,具有隔離性。set進去,get()出來

第一次get()為null,為解決,可以自定義類繼承ThreadLocal,自定義初始值

四.Lock

ReentrantLock為lock的實作類,同步鎖,比synchronized擁有更強大功能

4.1new ReentrantLock()出來,然後.lock()即上鎖,需要手動釋放鎖.unlock()。中間部分為同步。同步代碼間都需要搶同一把鎖

4.2Condition對象用于實作等待/通知,.await()必須先上鎖.

await()等同于wait()

await(long time,TimeUnit unit)等同于wait(long timeout)

signal()等同于notify()

signalAll()等同于notifyAll()

4.3通知部分線程使用多個Condition

4.4回憶生産消費者模型:生産方法如何,消費方法如何

4.5可以new ReentrantLock(boolean flag)生成公平/非公平鎖

4.6ReentrantLock幾個方法

getHoldCount():用lock()的次數
getQueueLength():等待擷取鎖的線程估計數
getWaitQueueLength(Condition condition):傳回等待與此鎖定相關的Condition的線程估計數
hasQueueThread(Thread thread):查詢指定線程是否正等待擷取鎖
hasWaiters(Condition condition):是否有線程正等待condition
isFair():是否公平
isHeldByCurrentThread():目前線程是否保持鎖
isLocked():查詢鎖是否由任意線程拿了
tryLock():鎖沒被别的線程拿我才拿
tryLock(long timeout,TimeUnit unit)
           

4.7ReentrantReadWriteLock

讀讀鎖不互斥

含寫操作都互斥

五.定時器Timer

5.1new Timer(true),自定義myTask extends TimerTask重寫run方法,設定時間,把myTask丢進去。

schedule(TimeTask task,Date time)

一個Timer可以運作多個TimerTask,但是隊列形式執行,後任務時間可能延遲。

5.2指定間隔周期性無限循環執行某一任務

timer.schedule(TimerTask task, Date firstTime, long period);

TimerTask的cancel()是将自身從任務隊列清除。

Timer的cancel()是将任務隊列清空。

5.3在此時間基礎上延遲指定毫秒執行一次TimerTask.

schedule(TimerTask task,Long delay)

5.4延遲指定毫秒,某間隔無限次數執行某一任務

schedule(TimerTask task,long delay,long period)