effective java 摘選條目分享 3 - concurrency
Post on 07-Aug-2015
34 Views
Preview:
TRANSCRIPT
2015/04/28 讀書會分享
Effective Java摘選條目分享 3
- Concurrency
Kane
大綱
Concurrency issues?atomicvolatilesynchronized 常用類別
wait / notifyThread Safety
You should already know ...
http://stackoverflow.com/questions/200469/what-is-the-difference-between-a-process-and-a-thread
You should already know ...
http://nerds.weddingpartyapp.com/tech/2014/06/20/primer-threading-handlers-android/
You should already know...
https://www3.ntu.edu.sg/home/ehchua/programming/java/J5e_multithreading.html
Concurrency issuesWhat is the most frequent concurrency issue you've encountered in Java?
http://stackoverflow.com/questions/461896/what-is-the-most-frequent-concurrency-issue-youve-encountered-in-java
Problemclass MyThread extends Thread { private boolean stop = false;
public void run() { while(!stop) { doSomeWork(); } }
public void setStop() { this.stop = true; }
調用了setStop(),
卻可能仍然不會停下。
暫存
http://javarevisited.blogspot.tw/2011/06/volatile-keyword-java-example-tutorial.html
volatile
http://www.slideshare.net/caroljmcdonald/java-concurrency-memory-model-and-trends-4961797
volatile 注意事項
對該變數的所有操作皆為原子操作?
http://stackoverflow.com/questions/3519664/difference-between-volatile-and-synchronized-in-java
考慮以下這段程式碼
public void updateCounter() {
if (counter == 1000) {
counter = 0;
} else {
counter++;
}
}
考慮以下這段程式碼
public void updateCounter() {
if (counter == 1000) {
counter = 0;
} else {
counter++;
}
}
從 main memory 讀取至 cache
在 cache 中更新值
在某個時機點寫回 main memory
Case: Two threads
if (counter == 1000) { counter = 0; } else { counter++; }
if (counter == 1000) {
counter = 0; } else { counter++; }
thread 1 thread 2
atomic
● 不可切割
● a++; 讀取 a
更新 a
synchronized
http://www.ibm.com/developerworks/library/j-jtp03304/
waiting for M’s lock
object locking / monitor
https://www.artima.com/insidejvm/ed2/threadsynchP.html
synchronized 注意事項
● 避免調用外部方法i.e. Template Method Pattern, callback, sub-class’s method, ...
● 重入 (reentrant)
常用類別 - 資料、容器
AtomicInteger, AtomicLong …
CopyOnWriteArrayList
ConcurrentHashMap
...
常用類別 - 資料、容器
AtomicInteger, AtomicLong …
CopyOnWriteArrayList
ConcurrentHashMap
...
putIfAbsent(k, v)-----------------------------if (containsKey(k)) { return put(k, v);} else { return get(k);}
常用類別 - 控制
Executor, ExecutorService, …
CountDownLatch
Semaphore
CyclicBarrier
常用類別 - 控制
Executor, ExecutorService, …
CountDownLatch
Semaphore
CyclicBarrier
更方便控制的 thread pool
常用類別 - 控制
Executor, ExecutorService, …
CountDownLatch
Semaphore
CyclicBarrier
等到扣完才動
同時間只有 n 個能進入
等到有 n 個到達 await() 後才動
wait / notify
1. 應優先使用 java.util.concurrent 提供的類別
2. wait 必在 loop 中使用
3. 優先考慮 notifyAll
https://codexplo.wordpress.com/2012/10/20/state-diagram-of-java-thread/
WHY: wait 必在 loop 中使用
1. notify 已經做了,先檢查條件可免 wait
2. 別人做了 notifyAll
3. spurious wakeupsynchronized (obj) {
while (<需等待的條件>) {
obj.wait();
}
}
spurious wake
scheduler可能因為一些原因而blackout中間可能錯失信號
故回復時會喚醒 thread,避免無限 waiting
關鍵字:POSIX Threads, Windows API, pthread_cond_wait, futex
優先考慮 notifyAll
1. 避免沒有收到 notify 的情況
2. 保護:wait 在 loop 中
Thread Safety1. immutable 不需要外部同步,因為instance狀態不變
2. unconditionally thread-safe 不需要外部同步
3. conditionally thread-safe 有些條件下必須使用外部同步
4. not thread-safe 使用者要自己控制同步
5. thread-hostile 就算都做了外部同步,也不行
Q&A
top related