第1章 Java多線程技能 1
1.1 進(jìn)程和線程的定義及多線程的優(yōu)點(diǎn) 1
1.2 使用多線程 5
1.2.1 繼承Thread類 6
1.2.2 使用常見的3個(gè)命令分析線程的信息 8
1.2.3 線程隨機(jī)性的展現(xiàn) 10
1.2.4 執(zhí)行start()的順序不代表執(zhí)行run()的順序 12
1.2.5 實(shí)現(xiàn)Runnable接口 14
1.2.6 使用Runnable接口實(shí)現(xiàn)多線程的優(yōu)點(diǎn) 15
1.2.7 public Thread(Runnable target)中的target參數(shù) 16
1.2.8 實(shí)例變量共享導(dǎo)致的“非線程安全”問題與相應(yīng)的解決方案 18
1.2.9 Servlet技術(shù)也會(huì)引起“非線程安全”問題 22
1.2.10 留意i--與System.out.println()出現(xiàn)的“非線程安全”問題 25
1.2.11 方法run()被JVM所調(diào)用 27
1.3 方法currentThread() 27
1.4 方法isAlive() 30
1.5 方法sleep(long millis) 33
1.6 方法sleep(long millis, int nanos) 34
1.7 方法StackTraceElement[] getStack-Trace() 35
1.8 方法static void dumpStack() 36
1.9 方法Map getAllStackTraces() 37
1.10 方法getId() 39
1.11 停止線程 40
1.11.1 停止不了的線程 41
1.11.2 判斷線程是不是停止?fàn)顟B(tài) 42
1.11.3 清除中斷狀態(tài)的使用場(chǎng)景 44
1.11.4 能停止的線程—異常法 48
1.11.5 在sleep狀態(tài)下停止 51
1.11.6 使用stop()暴力停止線程 53
1.11.7 方法stop()與java.lang.Thread-Death異常 55
1.11.8 使用stop()釋放鎖導(dǎo)致數(shù)據(jù)結(jié)果不一致 57
1.11.9 使用return;語句停止線程的缺點(diǎn)及相應(yīng)的解決方案 59
1.12 暫停線程 61
1.12.1 方法suspend()與resume()的使用 62
1.12.2 方法suspend()與resume()的缺點(diǎn)—獨(dú)占 63
1.12.3 方法suspend()與resume()的缺點(diǎn)—數(shù)據(jù)不完整 66
1.12.4 使用LockSupport類實(shí)現(xiàn)線程暫停與恢復(fù) 67
1.13 方法yield() 69
1.14 線程的優(yōu)先級(jí) 70
1.14.1 線程優(yōu)先級(jí)的繼承特性 71
1.14.2 線程優(yōu)先級(jí)的規(guī)律性 72
1.14.3 線程優(yōu)先級(jí)的隨機(jī)性 75
1.14.4 看誰跑得快 76
1.15 守護(hù)線程 78
1.16 并發(fā)與并行 79
1.17 同步與異步 80
1.18 多核CPU不一定比單核CPU運(yùn)行快 81
1.19 本章小結(jié) 82
第2章 對(duì)象及變量的并發(fā)訪問 83
2.1 synchronized同步方法 83
2.1.1 方法內(nèi)的變量是線程安全的 83
2.1.2 實(shí)例變量“非線程安全”問題及解決方案 85
2.1.3 同步synchronized在字節(jié)碼指令中的原理 88
2.1.4 多個(gè)對(duì)象多個(gè)鎖 90
2.1.5 synchronized方法將對(duì)象作為鎖 92
2.1.6 臟讀與解決 97
2.1.7 synchronized鎖重入 99
2.1.8 繼承環(huán)境下的鎖重入 100
2.1.9 出現(xiàn)異常,鎖自動(dòng)釋放 102
2.1.10 非同步方法?:不使用synchronized重寫方法 104
2.2 synchronized同步語句塊 106
2.2.1 synchronized方法的弊端 106
2.2.2 synchronized同步代碼塊的使用 109
2.2.3 用同步代碼塊解決同步方法的弊端 111
2.2.4 一半異步,一半同步 112
2.2.5 synchronized代碼塊間的同步性 114
2.2.6 方法println()也是同步的 116
2.2.7 驗(yàn)證synchronized(this)同步代碼塊是鎖定當(dāng)前對(duì)象的 117
2.2.8 將任意對(duì)象作為鎖 119
2.2.9 多個(gè)鎖就是異步執(zhí)行 121
2.2.10 驗(yàn)證方法被調(diào)用是隨機(jī)的 124
2.2.11 不同步導(dǎo)致的邏輯錯(cuò)誤與解決方案 125
2.2.12 細(xì)化驗(yàn)證3個(gè)結(jié)論 129
2.2.13 類對(duì)象的單例性 134
2.2.14 靜態(tài)同步?:synchronized方法與synchronized(class)代碼塊 135
2.2.15 同步synchronized方法可以對(duì)類的所有對(duì)象實(shí)例起作用 139
2.2.16 同步synchronized(class)代碼塊可以對(duì)類的所有對(duì)象實(shí)例起作用 141
2.2.17 String常量池特性與同步問題 143
2.2.18 synchronized方法無限等待問題與解決方案 146
2.2.19 多線程的死鎖 148
2.2.20 內(nèi)置類與靜態(tài)內(nèi)置類 150
2.2.21 內(nèi)置類與同步?:實(shí)驗(yàn)1 153
2.2.22 內(nèi)置類與同步?:實(shí)驗(yàn)2 155
2.2.23 鎖對(duì)象改變導(dǎo)致異步執(zhí)行 156
2.2.24 鎖對(duì)象不改變依然是同步執(zhí)行 159
2.2.25 同步寫法案例比較 161
2.2.26 方法holdsLock(Object obj)的使用 161
2.2.27 臨界區(qū) 162
2.3 volatile關(guān)鍵字 162
2.3.1 可見性的測(cè)試 163
2.3.2 原子性與非原子性的測(cè)試 171
2.3.3 禁止代碼重排序的測(cè)試 179
2.4 本章小結(jié) 190
第3章 線程間通信 191
3.1 wait/ notify機(jī)制 191
3.1.1 不使用wait/notify機(jī)制進(jìn)行通信的缺點(diǎn) 191
3.1.2 什么是wait/notify機(jī)制 194
3.1.3 wait/notify機(jī)制的原理 194
3.1.4 方法wait()的基本用法 195
3.1.5 使用代碼完整實(shí)現(xiàn)wait /notify機(jī)制 196
3.1.6 使用wait/notify機(jī)制實(shí)現(xiàn)線程銷毀 198
3.1.7 對(duì)業(yè)務(wù)代碼進(jìn)行封裝 200
3.1.8 線程狀態(tài)的切換 203
3.1.9 方法wait()導(dǎo)致鎖立即釋放 204
3.1.10 方法sleep()不釋放鎖 206
3.1.11 方法notify()不立即釋放鎖 206
3.1.12 方法interrupt()遇到方法wait() 208
3.1.13 方法notify()只通知一個(gè)線程 210
3.1.14 方法notifyAll()通知所有線程 212
3.1.15 方法wait(long)的基本用法 213
3.1.16 方法wait(long)自動(dòng)向下運(yùn)行的條件 215
3.1.17 通知過早與相應(yīng)的解決方案 218
3.1.18 等待條件發(fā)生變化 220
3.1.19 生產(chǎn)者/消費(fèi)者模式實(shí)現(xiàn) 224
3.1.20 在管道中傳遞字節(jié)流 239
3.1.21 在管道中傳遞字符流 241
3.1.22 利用wait/notify機(jī)制實(shí)現(xiàn)交叉?zhèn)浞? 244
3.1.23 方法sleep()和wait()的區(qū)別 247
3.2 方法join()的使用 247
3.2.1 學(xué)習(xí)方法join()前的鋪墊 247
3.2.2 用方法join()解決問題 248
3.2.3 方法join()和interrupt()出現(xiàn)異常 250
3.2.4 方法join(long)的使用 252
3.2.5 方法join(long)與sleep(long)的區(qū)別 254
3.2.6 方法join()后的代碼提前運(yùn)行 257
3.2.7 方法join(long millis, int nanos)的使用 261
3.3 類ThreadLocal的使用 262
3.3.1 方法get()與null 262
3.3.2 類ThreadLocal存取數(shù)據(jù)流程分析 263
3.3.3 驗(yàn)證線程變量的隔離性 266
3.3.4 解決get()返回null的問題 270
3.3.5 驗(yàn)證重寫initialValue()方法的隔離性 271
3.3.6 使用remove()方法的必要性 272
3.4 類InheritableThreadLocal的使用 276
3.4.1 類ThreadLocal不能實(shí)現(xiàn)值繼承 277
3.4.2 使用InheritableThreadLocal體現(xiàn)值繼承特性 278
3.4.3 值繼承特性在源代碼中的執(zhí)行流程 280
3.4.4 父線程有的值,子線程還是舊值?:不可變類型 285
3.4.5 子線程有的值,父線程還是舊值?:不可變類型 286
3.4.6 子線程可以感應(yīng)對(duì)象屬性值的變化?:可變類型 288
3.4.7 重寫childValue方法實(shí)現(xiàn)對(duì)繼承值的加工 291
3.5 本章小結(jié) 291
第4章 鎖的使用 292
4.1 使用ReentrantLock類 292
4.1.1 使用ReentrantLock實(shí)現(xiàn)同步 292
4.1.2 驗(yàn)證多代碼塊間的同步性 294
4.1.3 方法await()的錯(cuò)誤用法與相應(yīng)的解決方案 297
4.1.4 使用方法await()和方法signal()實(shí)現(xiàn)wait/notify 300
4.1.5 方法await()暫停的原理 302
4.1.6 通知部分線程?:錯(cuò)誤用法 306
4.1.7 通知部分線程?:正確用法 308
4.1.8 實(shí)現(xiàn)生產(chǎn)者/消費(fèi)者模式一對(duì)一交替打印 311
4.1.9 實(shí)現(xiàn)生產(chǎn)者/消費(fèi)者模式多對(duì)多交替打印 313
4.1.10 公平鎖與非公平鎖 315
4.1.11 方法getHoldCount()的使用 318
4.1.12 方法getQueueLength()的使用 319
4.1.13 方法getWaitQueueLength(Condition condition)的使用 321
4.1.14 方法hasQueuedThread(Thread thread)的使用 322
4.1.15 方法hasQueuedThreads()的使用 323
4.1.16 方法hasWaiters(Condition condition)的使用 324
4.1.17 方法isFair()的使用 326
4.1.18 方法isHeldByCurrentThread()的使用 326
4.1.19 方法isLocked()的使用 327
4.1.20 方法lockInterruptibly()的使用 328
4.1.21 方法tryLock()的使用 330
4.1.22 方法tryLock(long timeout, Time-Unit unit)的使用 331
4.1.23 方法await(long time, TimeUnit unit)的使用 333
4.1.24 方法awaitNanos(long nanos-Timeout)的使用 334
4.1.25 方法awaitUntil(Date deadline)的使用 335
4.1.26 方法awaitUninterruptibly()的使用 337
4.1.27 實(shí)現(xiàn)線程按順序執(zhí)行業(yè)務(wù) 339
4.2 使用ReentrantReadWriteLock類 342
4.2.1 類ReentrantLock的缺點(diǎn) 342
4.2.2 讀讀共享 344
4.2.3 寫寫互斥 344
4.2.4 讀寫互斥 345
4.2.5 寫讀互斥 346
4.3 本章小結(jié) 347
第5章 定時(shí)器 348
5.1 定時(shí)器的使用 348
5.1.1 方法schedule(TimerTask task, Date time)的測(cè)試 349
5.1.2 方法schedule(TimerTask task, Date f?irstTime, long period)的測(cè)試 357
5.1.3 方法schedule(TimerTask task, long delay)的測(cè)試 365
5.1.4 方法schedule(TimerTask task, long delay, long period)的測(cè)試 365
5.1.5 方法scheduleAtFixedRate(TimerTask task, Date f?irst-Time, long period)的測(cè)試 366
5.2 本章小結(jié) 374
第6章 單例模式與多線程 375
6.1 單例模式與多線程 375
6.1.1 立即加載/餓漢模式 375
6.1.2 延遲加載/懶漢模式 377
6.1.3 使用靜態(tài)內(nèi)置類實(shí)現(xiàn)單例模式 388
6.1.4 序列化與反序列化的單例模式實(shí)現(xiàn) 389
6.1.5 使用static代碼塊實(shí)現(xiàn)單例模式 392
6.1.6 使用enum枚舉數(shù)據(jù)類型實(shí)現(xiàn)單例模式 393
6.1.7 完善使用enum枚舉實(shí)現(xiàn)單例模式 394
6.2 本章小結(jié) 396
第7章 拾遺增補(bǔ) 397
7.1 線程的狀態(tài) 397
7.1.1 驗(yàn)證NEW、RUNNABLE和TERMINATED 399
7.1.2 驗(yàn)證TIMED_WAITING 400
7.1.3 驗(yàn)證BLOCKED 401
7.1.4 驗(yàn)證WAITING 403
7.2 線程組 404
7.2.1 線程對(duì)象關(guān)聯(lián)線程組?:一級(jí)關(guān)聯(lián) 404
7.2.2 線程對(duì)象關(guān)聯(lián)線程組?:多級(jí)關(guān)聯(lián) 406
7.2.3 線程組自動(dòng)歸屬特性 407
7.2.4 獲取根線程組 408
7.2.5 線程組內(nèi)加線程組 409
7.2.6 組內(nèi)的線程批量停止 409
7.2.7 遞歸取得與非遞歸取得組內(nèi)對(duì)象 410
7.3 Thread.activeCount()方法的使用 412
7.4 Thread.enumerate(Thread tarray[])方法的使用 412
7.5 再次驗(yàn)證線程執(zhí)行有序性 412
7.6 類SimpleDateFormat非線程安全 414
7.6.1 出現(xiàn)異常 415
7.6.2 解決方法1 417
7.6.3 解決方法2 418
7.7 線程中出現(xiàn)異常的處理 420
7.7.1 線程出現(xiàn)異常的默認(rèn)行為 420
7.7.2 使用setUncaughtException-Handler()方法進(jìn)行異常處理 421
7.7.3 使用setDefaultUncaught-ExceptionHandler()方法進(jìn)行異常處理 422
7.8 線程組內(nèi)處理異常 423
7.9 線程異常處理的優(yōu)先性 426
7.10 本章小結(jié) 431
第8章 并發(fā)集合框架 432
8.1 集合框架結(jié)構(gòu) 432
8.1.1 接口Iterable 432
8.1.2 接口Collection 432
8.1.3 接口List 433
8.1.4 接口Set 434
8.1.5 接口Queue 435
8.1.6 接口Deque 435
8.2 非阻塞隊(duì)列 435
8.2.1 類ConcurrentHashMap的使用 436
8.2.2 類ConcurrentSkipListMap的使用 442
8.2.3 類ConcurrentSkipListSet的使用 444
8.2.4 類ConcurrentLinkedQueue的使用 447
8.2.5 類ConcurrentLinkedDeque的使用 451
8.2.6 類CopyOnWriteArrayList的使用 453
8.2.7 類CopyOnWriteArraySet的使用 454
8.3 阻塞隊(duì)列 456
8.3.1 類ArrayBlockingQueue與公平/非公平鎖的使用 456
8.3.2 類PriorityBlockingQueue的使用 461
8.3.3 類LinkedBlockingQueue的使用 463
8.3.4 類LinkedBlockingDeque的使用 463
8.3.5 類SynchronousQueue的使用 463
8.3.6 類DelayQueue的使用 466
8.3.7 類LinkedTransferQueue的使用 467
8.4 本章小結(jié) 476
第9章 線程池類ThreadPoolExecutor的使用 477
9.1 Executor接口介紹 477
9.2 使用Executors工廠類創(chuàng)建線程池 481
9.2.1 使用newCachedThreadPool()方法創(chuàng)建無界線程池 481
9.2.2 驗(yàn)證newCachedThreadPool()方法創(chuàng)建線程池和線程復(fù)用特性 483
9.2.3 使用newCachedThreadPool (ThreadFactory)方法定制線程工廠 486
9.2.4 使用newCachedThread-Pool()方法創(chuàng)建無界線程池的缺點(diǎn) 487
9.2.5 使用newFixedThreadPool(int)
方法創(chuàng)建有界線程池 488
9.2.6 使用newSingleThread-Executor()方法創(chuàng)建單一線程池 490
9.3 ThreadPoolExecutor類的使用 491
9.3.1 隊(duì)列LinkedBlocking-Queue、ArrayBlocking-Queue和Synchronous-Queue的基本使用 491
9.3.2 構(gòu)造方法參數(shù)詳解 495
9.3.3 方法shutdown()和shutdownNow() 521
9.3.4 方法List shutdown-Now()返回值的作用 525
9.3.5 方法shutdown()和shutdown-Now()與中斷 527
9.3.6 方法isShutdown() 529
9.3.7 方法isTerminating()和isTerminated() 530
9.3.8 方法awaitTermination(long timeout,TimeUnit unit) 531
9.3.9 工廠ThreadFactory Thread UncaughtExceptionHandler處理異常 533
9.3.10 方法set/getRejected-ExecutionHandler() 537
9.3.11 方法allowsCoreThreadTime-Out和allowCoreThreadTime-Out(bool) 539
9.3.12 方法prestartCoreThread()和prestartAllCoreThreads() 541
9.3.13 方法getCompletedTask-Count() 542
9.3.14 線程池ThreadPoolExecutor的拒絕策略 543
9.3.15 方法afterExecute()和beforeExecute() 549
9.3.16 方法remove(Runnable)的使用 551
9.3.17 多個(gè)get方法的測(cè)試 555
9.4 本章小結(jié) 558