原子性
用來保證乙個程式操作被完整的執行,因為在cpu中是一條條指令執行,乙個編碼操作可能需要執行多條指令,具備原子性的操作,要麼完整的被執行,要麼不執行;單純的賦值、讀取操作是原子操作,多個原子操作結合在一起就是非原子操作。
多個操作要保證原子性就需要使用synchronized關鍵字和lock機制
有序性
保證程式的邏輯先後順序;與指令重排有關
可見性
在共享資料被多執行緒使用時,各個執行緒的任務執行前,cpu會一次讀取資料並儲存cpu快取記憶體中,如果某個執行緒修改了此共享資料的值(往往還儲存在cpu快取記憶體中,主存中還沒來得及更新,或者更新了別的執行緒已經讀取過了不清楚值的更改),這就是著名的資料不一致問題。cpu為什麼需要快取記憶體:可見性就是使得共享資料發生變化後立即更新主存並通知其他使用該變數的執行緒,將快取中的資料置為無效。
在計算機中,資料處理需要cpu與記憶體協作,但是記憶體(又稱之為主存)的讀寫速度遠低於cpu的處理速度,為了能夠很好的協作,cpu中有一塊快取記憶體的區域,用於將要處理的資料從記憶體(主存)中讀取出來並儲存在cpu快取記憶體中,然後cpu執行資料處理完成後,再重新重新整理記憶體(主存)中儲存的資料
附:資料不一致問題還有一種解決方式:匯流排鎖,不過這樣會導致cpu在訪問共享資料阻塞效率不夠好。
編碼器:在編譯器編譯程式原始碼成指令時,會在保證程式邏輯不改變的前提下優化指令的順序。volatile關鍵字就是保證被修飾變數的可見性和部分有序性的乙個修飾符這種編譯器優化指令的操作就是指令重排。
保障原子性,就是避免指定的操作被重排而是保持編寫順序的一種手段。通常以atomic開頭的變數表示原子操作變數
被volatile修飾的變數一般是共享變數,即多執行緒訪問、修改的變數,修飾後保證此變數被修改後,立即更新主存,並且通知已經讀取準備進行操作的其他執行緒cpu快取資料無效。
synchonized關鍵字修飾位置有兩個:
修飾方法(同步方法);
修飾**塊(同步**塊)。
兩者之間的區別是作用域不相同,修飾方法時,整個方法需要同步,多執行緒進入時必須獲取鎖,持有鎖的執行緒可進入執行,執行完成釋放鎖後,其他執行緒才可以獲取鎖進入。
根據鎖的型別有可以分為兩種:
類物件鎖:修飾靜態方法、修飾**塊時傳入.class作為鎖
物件鎖:修飾成員方法、修飾**塊傳入this作為鎖或者其他物件的例項作為鎖
類物件鎖,凡是這個類的例項都需要獲取鎖才能執行,此類多個例項都需同步;
物件鎖只針對同乙個例項,需要獲取鎖;
同一例項進入物件鎖時,有序執行,雖然獲取鎖的執行緒是隨機的;
不同例項進入物件鎖時,無序互不影響,多執行緒多例項所持物件鎖不同,互不影響結果。
同一例項/不同例項進入類物件鎖,有序執行;
wait與sleep的區別
wait是object的方法,sleep是thread的方法;
wait時,會釋放持有的當前執行緒的鎖,而sleep不會是釋放,將持鎖直到超時;
wait傳入乙個超時時間,並不一定會立即獲得資源,取決於其他執行緒是否釋放資源,以及wait是否能搶到資源;
wait不設定超時時間必須由notify/notifyall喚醒,多個object wait時,需要使用notifyall避免死鎖,因為notify是隨機喚醒的。
Tornado框架知識系列之三
在前面的示例中我們都是將服務埠的引數寫死在程式中,很不靈活。tornado為我們提供了乙個便捷的工具,tornado.options模組 全域性引數定義 儲存 轉換。用來定義options選項變數的方法,定義的變數可以在全域性的tornado.options.options中獲取使用,傳入引數 全域...
spring知識之三
條件化的bean 假設你希望乙個或多個bean只有在應用的類路徑下包含特定的庫時才建立。或者我們希望某個bean只有當另外某個特定的bean也宣告了之後才會建立。我們還可能要求只有某個特定的環境變數設定之後,才會建立某個bean。在spring 4之前,很難實現這種級別的條件化配置,但是spring...
《解剖PetShop》系列之三
解剖petshop 系列之三 三 petshop資料訪問層之訊息處理 在進行系統設計時,除了對安全 事務等問題給與足夠的重視外,效能也是乙個不可避免的問題所在,尤其是乙個b s結構的軟體系統,必須充分地考慮訪問量 資料流量 伺服器負荷的問題。解決效能的瓶頸,除了對硬體系統進行公升級外,軟體設計的合理...