Java併發程式設計實戰
Java併發程式設計實戰
基本資訊
- 原書名: Java Concurrency in Practice
- 原出版社:
- 作者:
- 譯者:
- 叢書名:
- 出版社:機械工業出版社
- ISBN:9787111370048
- 上架時間:2012-3-2
- 出版日期:2012 年2月
內容簡介
《java併發程式設計實戰》深入淺出地介紹了java執行緒和併發,是一本完美的java併發參考手冊。書中從併發性和執行緒安全性的基本概念出發,介紹瞭如何使用類庫提供的基本併發構建塊,用於避免併發危險、構造執行緒安全的類及驗證執行緒安全的規則,如何將小的執行緒安全類組合成更大的執行緒安全類,如何利用執行緒來提高併發應用程式的吞吐量,如何識別可並行執行的任務,如何提高單執行緒子系統的響應性,如何確保併發程式執行預期任務,如何提高併發程式碼的效能和可伸縮性等內容,最後介紹了一些高階主題,如顯式鎖、原子變數、非阻塞演算法以及如何開發自定義的同步工具類。
《java併發程式設計實戰》適合java程式開發人員閱讀。
《java併發程式設計實戰》適合java程式開發人員閱讀。
目錄
《java併發程式設計實戰》
對本書的讚譽
譯者序
前 言
第1章 簡介1
1.1 併發簡史1
1.2 執行緒的優勢2
1.2.1 發揮多處理器的強大能力2
1.2.2 建模的簡單性3
1.2.3 非同步事件的簡化處理3
1.2.4 響應更靈敏的使用者介面4
1.3 執行緒帶來的風險4
1.3.1 安全性問題5
1.3.2 活躍性問題7
1.3.3 效能問題7
1.4 執行緒無處不在7
第一部分 基礎知識
第2章 執行緒安全性11
2.1 什麼是執行緒安全性13
2.2 原子性14
對本書的讚譽
譯者序
前 言
第1章 簡介1
1.1 併發簡史1
1.2 執行緒的優勢2
1.2.1 發揮多處理器的強大能力2
1.2.2 建模的簡單性3
1.2.3 非同步事件的簡化處理3
1.2.4 響應更靈敏的使用者介面4
1.3 執行緒帶來的風險4
1.3.1 安全性問題5
1.3.2 活躍性問題7
1.3.3 效能問題7
1.4 執行緒無處不在7
第一部分 基礎知識
第2章 執行緒安全性11
2.1 什麼是執行緒安全性13
2.2 原子性14
.2.2.1 競態條件15
2.2.2 示例:延遲初始化中的競態條件16
2.2.3 複合操作17
2.3 加鎖機制18
2.3.1 內建鎖20
2.3.2 重入21
2.4 用鎖來保護狀態22
2.5 活躍性與效能23
第3章 物件的共享27
3.1 可見性27
3.1.1 失效資料28
3.1.2 非原子的64位操作29
3.1.3 加鎖與可見性30
3.1.4 volatile變數 30
3.2 釋出與逸出32
3.3 執行緒封閉35
3.3.1 ad-hoc執行緒封閉35
3.3.2 棧封閉36
3.3.3 threadlocal類37
3.4 不變性38
3.4.1 final域39
3.4.2 示例:使用volatile型別來發布不可變物件40
3.5 安全釋出41
3.5.1 不正確的釋出:正確的物件被破壞42
3.5.2 不可變物件與初始化安全性42
3.5.3 安全釋出的常用模式43
3.5.4 事實不可變物件44
3.5.5 可變物件44
3.5.6 安全地共享物件44
第4章 物件的組合46
4.1 設計執行緒安全的類46
4.1.1 收集同步需求47
4.1.2 依賴狀態的操作48
4.1.3 狀態的所有權48
4.2 例項封閉49
4.2.1 java監視器模式51
4.2.2 示例:車輛追蹤51
4.3 執行緒安全性的委託53
4.3.1 示例:基於委託的車輛追蹤器54
4.3.2 獨立的狀態變數55
4.3.3 當委託失效時56
4.3.4 釋出底層的狀態變數57
4.3.5 示例:釋出狀態的車輛追蹤器58
4.4 在現有的執行緒安全類中新增功能59
4.4.1 客戶端加鎖機制60
4.4.2 組合62
4.5 將同步策略文件化62
第5章 基礎構建模組66
5.1 同步容器類66
5.1.1 同步容器類的問題66
5.1.2 迭代器與concurrent-modificationexception68
5.1.3 隱藏迭代器69
5.2 併發容器70
5.2.1 concurrenthashmap71
5.2.2 額外的原子map操作72
5.2.3 copyonwritearraylist72
5.3 阻塞佇列和生產者-消費者模式73
5.3.1 示例:桌面搜尋75
5.3.2 序列執行緒封閉76
5.3.3 雙端佇列與工作密取77
5.4 阻塞方法與中斷方法77
5.5 同步工具類78
5.5.1 閉鎖79
5.5.2 futuretask80
5.5.3 訊號量82
5.5.4 柵欄83
5.6 構建高效且可伸縮的結果快取85
第二部分 結構化併發應用程式
第6章 任務執行93
6.1 線上程中執行任務93
6.1.1 序列地執行任務94
6.1.2 顯式地為任務建立執行緒94
6.1.3 無限制建立執行緒的不足95
6.2 executor框架96
6.2.1 示例:基於executor的web伺服器97
6.2.2 執行策略98
6.2.3 執行緒池98
6.2.4 executor的生命週期99
6.2.5 延遲任務與週期任務101
6.3 找出可利用的並行性102
6.3.1 示例:序列的頁面渲染器102
6.3.2 攜帶結果的任務callable與future103
6.3.3 示例:使用future實現頁面渲染器104
6.3.4 在異構任務並行化中存在的侷限106
6.3.5 completionservice:executor與blockingqueue106
6.3.6 示例:使用completionservice實現頁面渲染器107
6.3.7 為任務設定時限108
6.3.8 示例:旅行預定入口網站109
第7章 取消與關閉111
7.1 任務取消111
7.1.1 中斷113
7.1.2 中斷策略116
7.1.3 響應中斷117
7.1.4 示例:計時執行118
7.1.5 透過future來實現取消120
7.1.6 處理不可中斷的阻塞121
7.1.7 採用newtaskfor來封裝非標準的取消122
7.2 停止基於執行緒的服務124
7.2.1 示例:日誌服務124
7.2.2 關閉executorservice127
7.2.3 “毒丸”物件128
7.2.4 示例:只執行一次的服務129
7.2.5 shutdownnow的侷限性130
7.3 處理非正常的執行緒終止132
7.4 jvm關閉135
7.4.1 關閉鉤子135
7.4.2 守護執行緒136
7.4.3 終結器136
第8章 執行緒池的使用138
8.1 在任務與執行策略之間的隱性耦合138
8.1.1 執行緒飢餓死鎖139
8.1.2 執行時間較長的任務140
8.2 設定執行緒池的大小140
8.3 配置threadpoolexecutor141
8.3.1 執行緒的建立與銷燬142
8.3.2 管理佇列任務142
8.3.3 飽和策略144
8.3.4 執行緒工廠146
8.3.5 在呼叫建構函式後再定製threadpoolexecutor147
8.4 擴充套件 threadpoolexecutor148
8.5 遞迴演算法的並行化149
第9章 圖形使用者介面應用程式156
9.1 為什麼gui是單執行緒的156
9.1.1 序列事件處理157
9.1.2 swing中的執行緒封閉機制158
9.2 短時間的gui任務160
9.3 長時間的gui任務161
9.3.1 取消162
9.3.2 進度標識和完成標識163
9.3.3 swingworker165
9.4 共享資料模型165
9.4.1 執行緒安全的資料模型166
9.4.2 分解資料模型166
9.5 其他形式的單執行緒子系統167
第三部分 活躍性、效能與測試
第10章 避免活躍性危險169
10.1 死鎖169
10.1.1 鎖順序死鎖170
10.1.2 動態的鎖順序死鎖171
10.1.3 在協作物件之間發生的死鎖174
10.1.4 開放呼叫175
10.1.5 資源死鎖177
10.2 死鎖的避免與診斷178
10.2.1 支援定時的鎖178
10.2.2 透過執行緒轉儲資訊來分析死鎖178
10.3 其他活躍性危險180
10.3.1 飢餓180
10.3.2 糟糕的響應性181
10.3.3 活鎖181
第11章 效能與可伸縮性183
11.1 對效能的思考183
11.1.1 效能與可伸縮性184
11.1.2 評估各種效能權衡因素185
11.2 amdahl定律186
11.2.1 示例:在各種框架中隱藏的序列部分188
11.2.2 amdahl定律的應用189
11.3 執行緒引入的開銷189
11.3.1 上下文切換190
11.3.2 記憶體同步190
11.3.3 阻塞192
11.4 減少鎖的競爭192
11.4.1 縮小鎖的範圍(“快進快出”)193
11.4.2 減小鎖的粒度195
11.4.3 鎖分段196
11.4.4 避免熱點域197
11.4.5 一些替代獨佔鎖的方法198
11.4.6 監測cpu的利用率199
11.4.7 向物件池說“不”200
11.5 示例:比較map的效能200
11.6 減少上下文切換的開銷201
第12章 併發程式的測試204
12.1 正確性測試205
12.1.1 基本的單元測試206
12.1.2 對阻塞操作的測試207
12.1.3 安全性測試208
12.1.4 資源管理的測試212
12.1.5 使用回撥213
12.1.6 產生更多的交替操作214
12.2 效能測試215
12.2.1 在puttaketest中增加計時功能215
12.2.2 多種演算法的比較217
12.2.3 響應性衡量218
12.3 避免效能測試的陷阱220
12.3.1 垃圾回收220
12.3.2 動態編譯220
12.3.3 對程式碼路徑的不真實取樣222
12.3.4 不真實的競爭程度222
12.3.5 無用程式碼的消除223
12.4 其他的測試方法224
12.4.1 程式碼審查224
12.4.2 靜態分析工具224
12.4.3 面向方面的測試技術226
12.4.4 分析與監測工具226
第四部分 高階主題
第13章 顯式鎖227
13.1 lock與 reentrantlock227
13.1.1 輪詢鎖與定時鎖228
13.1.2 可中斷的鎖獲取操作230
13.1.3 非塊結構的加鎖231
13.2 效能考慮因素231
13.3 公平性232
13.4 在synchronized和reentrantlock之間進行選擇234
13.5 讀-寫鎖235
第14章 構建自定義的同步工具238
14.1 狀態依賴性的管理238
14.1.1 示例:將前提條件的失敗傳遞給呼叫者240
14.1.2 示例:透過輪詢與休眠來實現簡單的阻塞241
14.1.3 條件佇列243
14.2 使用條件佇列244
14.2.1 條件謂詞244
14.2.2 過早喚醒245
14.2.3 丟失的訊號246
14.2.4 通知247
14.2.5 示例:閥門類248
14.2.6 子類的安全問題249
14.2.7 封裝條件佇列250
14.2.8 入口協議與出口協議250
14.3 顯式的condition物件251
14.4 synchronizer剖析253
14.5 abstractqueuedsynchronizer254
14.6 java.util.concurrent同步器類中的 aqs257
14.6.1 reentrantlock257
14.6.2 semaphore與countdownlatch258
14.6.3 futuretask259
14.6.4 reentrantreadwritelock259
第15章 原子變數與非阻塞同步機制261
15.1 鎖的劣勢261
15.2 硬體對併發的支援262
15.2.1 比較並交換263
15.2.2 非阻塞的計數器264
15.2.3 jvm對cas的支援265
15.3 原子變數類265
15.3.1 原子變數是一種“更好的volatile”266
15.3.2 效能比較:鎖與原子變數267
15.4 非阻塞演算法270
15.4.1 非阻塞的棧270
15.4.2 非阻塞的連結串列272
15.4.3 原子的域更新器274
15.4.4 aba問題275
第16章 java記憶體模型277
16.1 什麼是記憶體模型,為什麼需要它277
16.1.1 平臺的記憶體模型278
16.1.2 重排序278
16.1.3 java記憶體模型簡介280
16.1.4 藉助同步281
16.2 釋出283
16.2.1 不安全的釋出283
16.2.2 安全的釋出284
16.2.3 安全初始化模式284
16.2.4 雙重檢查加鎖286
16.3 初始化過程中的安全性287
附錄a 併發性標註289
參考文獻291
2.2.2 示例:延遲初始化中的競態條件16
2.2.3 複合操作17
2.3 加鎖機制18
2.3.1 內建鎖20
2.3.2 重入21
2.4 用鎖來保護狀態22
2.5 活躍性與效能23
第3章 物件的共享27
3.1 可見性27
3.1.1 失效資料28
3.1.2 非原子的64位操作29
3.1.3 加鎖與可見性30
3.1.4 volatile變數 30
3.2 釋出與逸出32
3.3 執行緒封閉35
3.3.1 ad-hoc執行緒封閉35
3.3.2 棧封閉36
3.3.3 threadlocal類37
3.4 不變性38
3.4.1 final域39
3.4.2 示例:使用volatile型別來發布不可變物件40
3.5 安全釋出41
3.5.1 不正確的釋出:正確的物件被破壞42
3.5.2 不可變物件與初始化安全性42
3.5.3 安全釋出的常用模式43
3.5.4 事實不可變物件44
3.5.5 可變物件44
3.5.6 安全地共享物件44
第4章 物件的組合46
4.1 設計執行緒安全的類46
4.1.1 收集同步需求47
4.1.2 依賴狀態的操作48
4.1.3 狀態的所有權48
4.2 例項封閉49
4.2.1 java監視器模式51
4.2.2 示例:車輛追蹤51
4.3 執行緒安全性的委託53
4.3.1 示例:基於委託的車輛追蹤器54
4.3.2 獨立的狀態變數55
4.3.3 當委託失效時56
4.3.4 釋出底層的狀態變數57
4.3.5 示例:釋出狀態的車輛追蹤器58
4.4 在現有的執行緒安全類中新增功能59
4.4.1 客戶端加鎖機制60
4.4.2 組合62
4.5 將同步策略文件化62
第5章 基礎構建模組66
5.1 同步容器類66
5.1.1 同步容器類的問題66
5.1.2 迭代器與concurrent-modificationexception68
5.1.3 隱藏迭代器69
5.2 併發容器70
5.2.1 concurrenthashmap71
5.2.2 額外的原子map操作72
5.2.3 copyonwritearraylist72
5.3 阻塞佇列和生產者-消費者模式73
5.3.1 示例:桌面搜尋75
5.3.2 序列執行緒封閉76
5.3.3 雙端佇列與工作密取77
5.4 阻塞方法與中斷方法77
5.5 同步工具類78
5.5.1 閉鎖79
5.5.2 futuretask80
5.5.3 訊號量82
5.5.4 柵欄83
5.6 構建高效且可伸縮的結果快取85
第二部分 結構化併發應用程式
第6章 任務執行93
6.1 線上程中執行任務93
6.1.1 序列地執行任務94
6.1.2 顯式地為任務建立執行緒94
6.1.3 無限制建立執行緒的不足95
6.2 executor框架96
6.2.1 示例:基於executor的web伺服器97
6.2.2 執行策略98
6.2.3 執行緒池98
6.2.4 executor的生命週期99
6.2.5 延遲任務與週期任務101
6.3 找出可利用的並行性102
6.3.1 示例:序列的頁面渲染器102
6.3.2 攜帶結果的任務callable與future103
6.3.3 示例:使用future實現頁面渲染器104
6.3.4 在異構任務並行化中存在的侷限106
6.3.5 completionservice:executor與blockingqueue106
6.3.6 示例:使用completionservice實現頁面渲染器107
6.3.7 為任務設定時限108
6.3.8 示例:旅行預定入口網站109
第7章 取消與關閉111
7.1 任務取消111
7.1.1 中斷113
7.1.2 中斷策略116
7.1.3 響應中斷117
7.1.4 示例:計時執行118
7.1.5 透過future來實現取消120
7.1.6 處理不可中斷的阻塞121
7.1.7 採用newtaskfor來封裝非標準的取消122
7.2 停止基於執行緒的服務124
7.2.1 示例:日誌服務124
7.2.2 關閉executorservice127
7.2.3 “毒丸”物件128
7.2.4 示例:只執行一次的服務129
7.2.5 shutdownnow的侷限性130
7.3 處理非正常的執行緒終止132
7.4 jvm關閉135
7.4.1 關閉鉤子135
7.4.2 守護執行緒136
7.4.3 終結器136
第8章 執行緒池的使用138
8.1 在任務與執行策略之間的隱性耦合138
8.1.1 執行緒飢餓死鎖139
8.1.2 執行時間較長的任務140
8.2 設定執行緒池的大小140
8.3 配置threadpoolexecutor141
8.3.1 執行緒的建立與銷燬142
8.3.2 管理佇列任務142
8.3.3 飽和策略144
8.3.4 執行緒工廠146
8.3.5 在呼叫建構函式後再定製threadpoolexecutor147
8.4 擴充套件 threadpoolexecutor148
8.5 遞迴演算法的並行化149
第9章 圖形使用者介面應用程式156
9.1 為什麼gui是單執行緒的156
9.1.1 序列事件處理157
9.1.2 swing中的執行緒封閉機制158
9.2 短時間的gui任務160
9.3 長時間的gui任務161
9.3.1 取消162
9.3.2 進度標識和完成標識163
9.3.3 swingworker165
9.4 共享資料模型165
9.4.1 執行緒安全的資料模型166
9.4.2 分解資料模型166
9.5 其他形式的單執行緒子系統167
第三部分 活躍性、效能與測試
第10章 避免活躍性危險169
10.1 死鎖169
10.1.1 鎖順序死鎖170
10.1.2 動態的鎖順序死鎖171
10.1.3 在協作物件之間發生的死鎖174
10.1.4 開放呼叫175
10.1.5 資源死鎖177
10.2 死鎖的避免與診斷178
10.2.1 支援定時的鎖178
10.2.2 透過執行緒轉儲資訊來分析死鎖178
10.3 其他活躍性危險180
10.3.1 飢餓180
10.3.2 糟糕的響應性181
10.3.3 活鎖181
第11章 效能與可伸縮性183
11.1 對效能的思考183
11.1.1 效能與可伸縮性184
11.1.2 評估各種效能權衡因素185
11.2 amdahl定律186
11.2.1 示例:在各種框架中隱藏的序列部分188
11.2.2 amdahl定律的應用189
11.3 執行緒引入的開銷189
11.3.1 上下文切換190
11.3.2 記憶體同步190
11.3.3 阻塞192
11.4 減少鎖的競爭192
11.4.1 縮小鎖的範圍(“快進快出”)193
11.4.2 減小鎖的粒度195
11.4.3 鎖分段196
11.4.4 避免熱點域197
11.4.5 一些替代獨佔鎖的方法198
11.4.6 監測cpu的利用率199
11.4.7 向物件池說“不”200
11.5 示例:比較map的效能200
11.6 減少上下文切換的開銷201
第12章 併發程式的測試204
12.1 正確性測試205
12.1.1 基本的單元測試206
12.1.2 對阻塞操作的測試207
12.1.3 安全性測試208
12.1.4 資源管理的測試212
12.1.5 使用回撥213
12.1.6 產生更多的交替操作214
12.2 效能測試215
12.2.1 在puttaketest中增加計時功能215
12.2.2 多種演算法的比較217
12.2.3 響應性衡量218
12.3 避免效能測試的陷阱220
12.3.1 垃圾回收220
12.3.2 動態編譯220
12.3.3 對程式碼路徑的不真實取樣222
12.3.4 不真實的競爭程度222
12.3.5 無用程式碼的消除223
12.4 其他的測試方法224
12.4.1 程式碼審查224
12.4.2 靜態分析工具224
12.4.3 面向方面的測試技術226
12.4.4 分析與監測工具226
第四部分 高階主題
第13章 顯式鎖227
13.1 lock與 reentrantlock227
13.1.1 輪詢鎖與定時鎖228
13.1.2 可中斷的鎖獲取操作230
13.1.3 非塊結構的加鎖231
13.2 效能考慮因素231
13.3 公平性232
13.4 在synchronized和reentrantlock之間進行選擇234
13.5 讀-寫鎖235
第14章 構建自定義的同步工具238
14.1 狀態依賴性的管理238
14.1.1 示例:將前提條件的失敗傳遞給呼叫者240
14.1.2 示例:透過輪詢與休眠來實現簡單的阻塞241
14.1.3 條件佇列243
14.2 使用條件佇列244
14.2.1 條件謂詞244
14.2.2 過早喚醒245
14.2.3 丟失的訊號246
14.2.4 通知247
14.2.5 示例:閥門類248
14.2.6 子類的安全問題249
14.2.7 封裝條件佇列250
14.2.8 入口協議與出口協議250
14.3 顯式的condition物件251
14.4 synchronizer剖析253
14.5 abstractqueuedsynchronizer254
14.6 java.util.concurrent同步器類中的 aqs257
14.6.1 reentrantlock257
14.6.2 semaphore與countdownlatch258
14.6.3 futuretask259
14.6.4 reentrantreadwritelock259
第15章 原子變數與非阻塞同步機制261
15.1 鎖的劣勢261
15.2 硬體對併發的支援262
15.2.1 比較並交換263
15.2.2 非阻塞的計數器264
15.2.3 jvm對cas的支援265
15.3 原子變數類265
15.3.1 原子變數是一種“更好的volatile”266
15.3.2 效能比較:鎖與原子變數267
15.4 非阻塞演算法270
15.4.1 非阻塞的棧270
15.4.2 非阻塞的連結串列272
15.4.3 原子的域更新器274
15.4.4 aba問題275
第16章 java記憶體模型277
16.1 什麼是記憶體模型,為什麼需要它277
16.1.1 平臺的記憶體模型278
16.1.2 重排序278
16.1.3 java記憶體模型簡介280
16.1.4 藉助同步281
16.2 釋出283
16.2.1 不安全的釋出283
16.2.2 安全的釋出284
16.2.3 安全初始化模式284
16.2.4 雙重檢查加鎖286
16.3 初始化過程中的安全性287
附錄a 併發性標註289
參考文獻291
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16566727/viewspace-718339/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java併發程式設計實戰--FutureTaskJava程式設計
- Java併發程式設計實戰--Amdahl定律Java程式設計
- Java併發系列—併發程式設計挑戰Java程式設計
- Java併發程式設計實戰總結 (一)Java程式設計
- 《JAVA併發程式設計實戰》顯式鎖Java程式設計
- Java併發程式設計實戰(4)- 死鎖Java程式設計
- Java併發程式設計實戰——讀後感Java程式設計
- Java併發程式設計實戰--筆記三Java程式設計筆記
- Java併發程式設計實戰--筆記四Java程式設計筆記
- Java併發程式設計實戰--筆記二Java程式設計筆記
- Java併發程式設計實戰--this引用逸出Java程式設計
- Java併發程式設計實戰--筆記一Java程式設計筆記
- Java併發程式設計實戰--閉鎖 CountDownLatchJava程式設計CountDownLatch
- Java併發程式設計實戰--事實不可變物件Java程式設計物件
- 【面試實戰】# 併發程式設計面試程式設計
- 《JAVA併發程式設計實戰》任務執行Java程式設計
- 《JAVA併發程式設計實戰》取消和關閉Java程式設計
- 《JAVA併發程式設計實戰》物件的組合Java程式設計物件
- 實戰Java高併發程式設計模式視訊Java程式設計設計模式
- Java併發程式設計實戰--計數訊號量(Semaphore)Java程式設計
- Java併發程式設計 - 第十一章 Java併發程式設計實踐Java程式設計
- 《JAVA併發程式設計實戰》基礎構建模組Java程式設計
- 併發程式設計實戰——鎖分段程式設計
- Java併發程式設計實踐Java程式設計
- Java併發程式設計實戰--顯式的Condition物件Java程式設計物件
- Java併發程式設計實戰--讀書筆記(目錄)Java程式設計筆記
- java 併發程式設計Java程式設計
- Java併發程式設計Java程式設計
- Java併發程式設計實戰 04死鎖了怎麼辦?Java程式設計
- Java併發程式設計實戰-王寶令-極客時間Java程式設計
- Java併發程式設計實戰(5)- 執行緒生命週期Java程式設計執行緒
- Java併發程式設計實戰系列16之Java記憶體模型(JMM)Java程式設計記憶體模型
- JAVA實現網路程式設計之併發程式設計Java程式設計
- 【Java併發程式設計】併發程式設計大合集-值得收藏Java程式設計
- Java併發程式設計實踐-this溢位Java程式設計
- JAVA併發程式設計實踐 下載Java程式設計
- java併發程式設計實戰筆記(部分實戰未看,老舊章節跳過)Java程式設計筆記
- Java併發程式設計實戰筆記3:基礎構建模組Java程式設計筆記