java并发编程实践 读书笔记_Java - 并发编程实践(读书笔记)
[注] 同步機制保證:1)原子性 2)內存可見性;
Volatile變量只能保證:1)可見性; - 恰當的同步,同步的弱形式,確保對一個變量的更新以可預見的方式告知其他線程。
[注] 用鎖來協調訪問變量時,每次訪問變量都需要用同一個鎖。鎖不僅僅是關于同步與互斥的,也是關于內存可見的。
為了保證所有線程都能夠看到共享的、可變變量的最新值,讀取和寫入線程必須使用公共的鎖進行同步。
[注] Java提供的內部鎖是可重進入的,因為線程在試圖獲取它自己占有的鎖時,請求會成功。重進入(Reenter)意味著鎖的請求是基于"每線程",而不是基于"每調用";
[注] **本地(基于棧的)變量,不會被跨線程共享,因此不需要同步;
每個線程都會有一個棧內存,其存儲的變量只能在其所屬線程中可見,棧內存可以理解為線程的私有內存;
[注] 線程中斷是一個協作機制,每一個線程都有一個boolean類型的中斷狀態,在中斷的時候,這個中斷狀態被設置為true。
阻塞庫函數,比如:Thread.sleep()和Object.wait(),試圖監測線程何時被中斷,它們對中斷的響應表現為:清除中斷狀態,拋出InterruptedException,這表示阻塞操作因為中斷而提前結束。
[注] Volatile變量 vs 鎖 :
Volatile變量與鎖相比是更輕量的同步機制,它們不會引起上下文的切換和線程調度。然而,Volatile變量與鎖相比有一些局限性:
盡管它們提供了相似的可見性保證,但是它們不能用于構建原子化的復合操作。這意味著當一個變量依賴其他變量時,或者當前變量的新值依賴于舊值時,是不能用Volatile變量的。
[注] 原子變量類 vs 鎖 :
原子變量比鎖更精巧,更輕量,因為它不會引起線程的掛起和重新調度;
CAS:compare and set; 非阻塞算法;
術語:檢查并運行
[注] 條件隊列:
Object中的wait、notify、notifyAll方法構成了內部條件隊列的API;
一個對象的內部鎖與它的內部條件隊列是相關的,為了能夠調用對象X的任一個條件隊列方法,必須持有對象的鎖;
條件謂語涉及狀態變量,狀態變量是由鎖保護的,所以測試條件謂語之前,必須先持有鎖;
* 鎖、條件謂語和條件變量之間的三元關系,涉及條件謂詞的變量必須由鎖保護,檢查條件謂詞時以及調用wait和notify時,必須持有鎖對象;
狀態依賴方法的規范式:
void stateDependentMethod() throws InterruptedException{
//條件謂語必須被鎖守護
synchronized(lock){
while(!conditionPredicate()){
lock.wait();
}
//現在,對象處于期望的狀態中
}
}
Obejct.wait 內部流程:
1) 會自動釋放鎖,并請求OS掛起當前線程,讓其他線程可以獲得該鎖進而修改對象的狀態;
2) 線程被喚醒時,wait會重新請求與條件隊列相關聯的鎖;
Object.notify:JVM從條件隊列中等待的眾多線程中挑選出一個并把它喚醒;
Object.notifyAll:JVM喚醒條件隊列中等待的所有線程;(通常使用notifyAll)
[注] 一個公平的條件隊列可以確保線程從等待集中釋放的相對順序,內部條件隊列并不提供公平隊列,顯式的Condition可以提供公平/非公平隊列的選擇;
[注]Condition是顯式的條件隊列(await、signal、signalAll等方法),一個Condition與一個單獨的Lock相關聯,Lock.newCondition()可以創建一個Condition;
[注] Lock:顯式鎖,可中斷的鎖獲取請求,中斷將拋出InterruptedException;
public boolean sendOnShareLine(String message) throws InterruptedException{
lock.lockInterruptibly();
try{
return cancellableSendOnSharedLine(message);
}finally{
lock.unlock();
}
}
private boolean cancellableSendOnSharedLine(String message)
throws InterruptedException{ ... }
阻塞隊列 BlockingQueue : LinkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue
1)阻塞方法:put()、take()
2)非阻塞方法:offer()、poll()
Executor框架 -任務執行框架:將任務的提交與任務的執行體進行解耦,可以簡單的為給定的任務制定執行策略。
類庫提供了一個靈活的線程池實現:ThreadPoolExecutor,以及一些有用的預設配置,可以通過?Executors中的靜態工廠方法創建一個線程池:
newFixedThreadPool
newCachedThreadPool
newScheduledThreadPool
newSingleThreadExecutor
為了解決執行服務的生命周期問題,ExecutorService接口擴展了Executor,添加了一些用于生命周期管理的方法,同時還有一些用于任務提交的便利方法。
想要使用Executor,還必須能夠將任務描述為Runnable。Executor框架使用Runnable作為其任務的基本表達形式。
- Runnable 只是相當有限的抽象,run方法不能返回值或者拋出受檢查的異常;
- Callable 可攜帶結果的任務,可以把其他類型的任務封裝成一個Callable;
一個Executor執行的任務的生命周期有4個階段:創建、提交、開始和完成。
Future 用以描述"任務"的生命周期,提供方法來獲得任務的結果、取消任務以及檢查任務是否已經完成還是被取消。
有很多種方法可以創建一個描述任務的Future:
- 將一個Runnable或一個Callable提交給executor,然后得到一個描述任務執行的Future,如:ExecutorService.submit()方法;
- 顯示為給定的Runnable或Callable實例化一個FutureTask;
public interface Callable{
V call() throws Exception;
}
public interface Future{
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException,ExecutionException,CancellationException;
V get(long timeout,TimeUnit unit)
throws InterruptedException,ExecutionException,CancellationException,TimeoutException;
}
可參考文章:
Java并發編程實戰讀后感?http://www.jianshu.com/p/c072cb0b4763
并發編程網-高質量并發譯文?http://ifeve.com/doug-lea/
總結
以上是生活随笔為你收集整理的java并发编程实践 读书笔记_Java - 并发编程实践(读书笔记)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 抽象工厂 类图_spring学
- 下一篇: 曼哈顿距离java实现_基于javasc