Java7并發編程實戰手冊
線程管理
Thread/Runnable/Thread.State
線程的信息獲取和設置
線程的中斷
sleep/yield
join
daemon
UncaughtExceptionHandler
Thread#setDefaultUncaughtExceptionHandler
ThreadLocal/InheritableThreadLocal
ThreadGroup
uncaughtException
ThreadFactory
進群:697699179可以獲取Java各類入門學習資料!
這是我的微信公眾號【編程study】各位大佬有空可以關注下,每天更新Java學習方法,感謝!
學習中遇到問題有不明白的地方,推薦加小編Java學習群:697699179內有視頻教程 ,直播課程 ,等學習資料,期待你的加入
線程同步基礎
synchronized 同步方法 this
synchronized 屬性對象 object
同步代碼塊中使用條件
Object#wait/notify/notifyAll
虛假喚醒(while)
Lock
ReentrantLock
try/finally
ReadWriteLock
公平性 fair
Condition
while
lock/unlock之間
線程同步輔助類
Semaphore
內部計數器
acquire/release
acquireUninterruptibly
忽略線程中斷且不會拋出任何異常
CountDownLatch
內部計數器被初始化之后就不能被再次初始化,唯一能改值的是countDown
CylicBarrier
BrokenBarrierException
reset
Phaser
在每一步結束的位置對線程進行同步,當所有的線程都完成了這一步,才允許執行下一步
Phaser(3) 指定參與階段同步的線程數是3個
被Phaser類置于休眠的線程不會響應中斷事件
awaitAdvanceInterruptibly(int phaser),被中斷會拋出InterruptedException
onAdavance,階段改變時被自動執行
Exchanger
只能同步兩個線程
exchange調用后將休眠直到其他的線程到達
線程執行器
ThreadPoolExecutor/Executors
shutdown,當執行完所有待運行的任務后,它將結束執行,調用完畢立即返回,結合awaitTermination判斷是否線程池是否關閉
awaitTermination(long timeout, TimeUnit unit)
提供很多方法獲取自身狀態的信息
newCachedThreadPool/newFixedThreadPool
Future/Callbale
submit
call() throws Exception
ThreadPoolExecutor#invokeAny
返回第一個完成任務且沒有拋出異常的任務的執行結果
ThreadPoolExecutor#invokeAll
等待所有任務的完成
landon:是否可以用這個方法做場景心跳
while(!isDone)? {? ? -longstartTime = getCurrent()? ? - 場景調度器提交場景任務,等待所有場景任務執行完畢(invokeAll),這樣亦可以保證潛在的順序問題,因為每次都是將當前的tick執行完畢? ? - 而非之前submit,如果一次tick執行超過50ms則下次循環又會向線程池提交任務,會出現同一個任務多個線程執行的潛在情況? ? -longendTime = getCurrent()? ? -longsleepTime = startTime + TickInterval - endTime? ? -if(sleepTime >0) sleep(sleepTime)? ? -elseprintln("busy,oneTick executeTime:"+ sleepTime)? }
ScheduledThreadPoolExecutor
schedule
scheduleAtFixedRate
scheduleWithFixDelay
Future
cancel
get
FutureTask
done,允許在執行器中的任務執行結束之后還可以執行一些代碼
FutureTask?implements RunnableFuture
FutureTask(Callable?callable)
CompletionService
submit,提交任務
poll/take,獲取任務已經完成的Future對象
即任務完成后將Future對象放到一個完成的阻塞隊列中
RejectedExecutionHandler
Fork/Join框架
分治
fork-將一個任務拆分成更小的多個任務
join-等待子任務的完成執行
工作竊取算法-work-stealing algorithm
ForkJoinPool
ForkJoinTask
RecursiveAction 任務無返回結果
RecursiveTask 任務有返回結果
遞歸
if(problemsize>defaultsize){? ? tasks = divide(task)? ? execute(tasks) }else{resolve problem using another algorithm}
Task extends RecursiveAction // 無返回結果
compute
if(...)// divide{Taskt1 =newTask(...)Taskt2 =newTask(...)? invokeAll(t1,t2)// 同步調用,執行創建的多個子任務}else{...}
ForkJoinPool#execute(task) --默認創建一個線程數等于計算機cpu數目的線程池
合并任務的結果
if(problemsize>defaultsize)? tasks = divide(task)? execute(tasks)? groupResultsreturnresultelseresolve problemreturnresult
ForkJoinTask#get 等待返回任務計算結果
異步運行任務
同步方式如invokeAll,任務被掛起,直到任務被發送到fork/join線程池中執行。該方式允許ForkJoinPool采用工作竊取算法
異步方式如fork時(立即返回),無法使用該算法
ForkJoinTask#V join()
get和join有區別
任務中拋出異常
ForkJoinTask#isCompletedAbnormally 檢查主任務或者子任務是否拋出了異常
getException 獲取異常信息
任務拋出運行時異常,會影響其父任務...父任務..
取消任務
在任務開始前可以取消
例:在數字數組中尋找一組數字,拆分為更小的問題,但僅關心數字的一次出現。當我們找到他時,就會取消其他子任務
可存儲發送到線程池中的所有任務,當發現當前任務找到數字后,取消非當前任務的所有任務
如果任務正在運行或者已經執行結束,則不能取消,cancel返回false。因此可以嘗試去取消所有的任務而不用擔心可能帶來的間接影響
并發集合
ConcurrentLinkedDeque 非阻塞
getFirst.../peekFirst.../removeFirst.../pollFirst... - 雙端隊列
LinkedBlockingDeque 阻塞
put/take/poll... 雙端隊列
PriorityBlockingQueue
隊列的元素必須實現Comparable接口
按照排序結果決定插入元素的位置
DelayQueue
元素必須實現Delayed接口
public interface Delayed extends Comparable
兩個待實現方法
compareTo(Delayed o)
getDelay(Timeunit unit)
從隊列取元素時,到期的元素會返回(未來的元素等待到期_延遲時間)
landon:是否可以用于游戲服務器中的計時器?如果有多個timer?按照到期時間排隊_
ConcurrentSkipListMap
根據鍵值排序所有元素
內部機制-Skip List
# firstEntry/lastEntry/subMap/...
landon:可以和TreeMap做比較,一個線程不安全,一個線程安全
ThreadLocalRandom
# current,該方法是一個靜態方法,如果調用線程還未關聯隨機數對象,就會初始化一個(localInit)
Atomic Variable
compareAndSet,這是是最主要的方法
判斷內存變量的值是否是expect,如果是說明未被其他線程改過,可以直接用update新值更新
否則說明被其他線程改過,進而可以選擇下一步處理方式
AtomicReference#public final boolean compareAndSet(V expect, V update)
CAS
AtomicIntegerArray -原子數組
LinkedTransferQueue
AtomicReference--實現單例
publicclassSingleton{privatestaticfinalAtomicReference INSTANCE =newAtomicReference();privateSingleton(){}publicstaticSingletongetInstance(){for(;;) {? ? ? ? ? ? ? ? ? ? Singleton current = INSTANCE.get();if(current !=null) {returncurrent;? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? current =newSingleton();if(INSTANCE.compareAndSet(null, current)) {returncurrent;? ? ? ? ? ? ? ? ? }? ? ? ? ? }? ? ? ? }}
定制并發類
定制ThreadPoolExecutor
繼承該類
覆寫_記得調用super
shutdown
shutdownNow
輸出如等待執行的任務數目 getQueue().size...
getCompletedTaskCount,獲得已執行過的任務數
getActiveCount,獲得正在執行的任務數
beforeExecute
afterExecute
實現基于優先級的Executor類
ThreadPoolExector參數傳入PriorityBlockingQueue
如果是fixed兩個線程,那么前2個任務是被2個線程執行的;后面的排隊任務按照優先級順序執行
實現ThreadFactory接口生成定制線程
覆寫newThread方法
返回的Thread可以是定制的Thread對象(MyThread extends Thread)
可外部直接調用Threadfactory#newThread返回線程
在Executor對象中使用ThreadFactory
線程池參數中指定線程工廠
Executors內部有一個DefaultThreadFactory
Executors$DefaultThreadFactory
定制運行在定時線程池中的任務
繼承ScheduledThreadPoolExecutor
覆寫protected?RunnableScheduledFuture?decorateTask(
Runnable runnable, RunnableScheduledFuture?task)
可自定義一個調度類extends FutureTask?implements RunnableScheduledFuture參考ScheduledThreadPoolExecutor$ScheduledFutureTask
通過實現ThreadFactory接口為Fork/Join框架生成定制線程
ForkJoinPool內部實現
一個任務隊列,存放等待被執行的任務
一個執行這些任務的線程池
ForkJoinWorkerThread持有一個ForkJoinPool.WorkQueue workQueue
work-stealing mechanics
MyWorkerThread extends ForkJoinWorkerThread
onStart
onTermination
調用super
MyWorkerThreadFactory implements ForkJoinWorkerThreadFactory
newThread
定制運行在Fork/Join框架中的任務
MyWorkTask extends ForkJoinTask(Void)
getRawResult
exec
調用compute抽象方法
實現定制Lock類
ReentrantLock內部有一個很重要的類Sync(AQS)
abstract static class Sync extends AbstractQueuedSynchronizer
static final class FairSync extends Sync
static final class NonfairSync extends Sync
自定義實現一個MyAbstractQueuedSynchronizer extends AbstractQueuedSynchronizer
tryActuire
tryRelease
自定義實現MyLock implements Lock
lock
unlock
tryLock
newCondition
實現基于優先級的傳輸隊列
MyPriorityTransferQueue?extends PriorityBlockingQueue?implements TransferQueuetryTransfer
transfer
hasWaitingConsumer
getWaitingConsumerCount
take
實現自己的原子對象
MyCounter extends AtomicInteger
for(;;)? ? {intvalue=get();if(value==10)returnfalse;else{intnewValue =value+1;? ? ? boolean changed = compareAndSet(value,newValue);if(changed)returntrue;? ? ? }? ? }
測試并發應用程序
監控Lock接口
ReentrantLock內部方法都是protected的,所以可以繼承
MyLock extends ReentrantLock
調用Thread getOwner()
調用Collection?getQueuedThreads()
...
監控Phaser類
getPhase
getRegisteredParties
getArrivedParties
...
監控執行器框架
ThreadPoolExecutor
getPoolSize
getCorePoolSize
getActiveCount
getTaskCount
...
監控Fork/Join池
getPoolSize
getParallelism
getActiveThreadCount
getStealCount
...
輸出高效的日志信息
輸出必要的信息
為消息設定恰當的級別
使用FindBugs分析并發代碼
配置Eclipse調試并發代碼
可選擇Default suspend policy for new breakpoints的值為Suspend VM
默認為Suspend Thread
配置NetBeans調試并發代碼
使用MultithreadedTC測試并發代碼
MultithreadedTestCase
waitForTick