多線程共享資源,比如一個對象的內存,怎樣保證多個線程不會同時訪問(讀取或寫入)這個對象,這就是並發最大的難題,因此產生了 互斥機制(鎖)。
using the same monitor lock.
獲取鎖後,該線程本地存儲失效,臨界區(就是獲得鎖後釋放鎖之前 的代碼區)從主存獲取數據,並在釋放鎖後刷入主存。
互斥:
保證臨界區代碼線程間互斥。
synchronized實現同步的基礎:
java中每個對象都可以作為鎖
一個任務可以多次獲得鎖,比如在一個線程中調用一個對象的 synchronized標記的方法,在這個方法中調用第二個synchronized標記的方法,然後在第二個synchronized方法中調用第三個synchronized方法。一個線程每次進入一個synchronized方法中JVM都會跟蹤加鎖的次數,每次+1,當該這個方法執行完畢,JVM計數-1;當JVM計數為0時,鎖完全被釋放,其他線程可以訪問該變數。
在使用並發時將對象的field設為private 很重要!尤其是使用static變數(evil static variable) 使用 Lock lock =new ReentrantLock()的問題是代碼不夠優雅,增加代碼量;我們一般都是使用synchronized實現互斥機制。但是1.當代碼中拋出異常時,顯示鎖的finally里可以進行資源清理工作。2.ReentrantLock還給我們更細粒度的控制力
2. 有哪些Java web里的並發框架,都有哪些
一、並發是一種需求,以下先介紹一下javaweb對於高並發的處理思路:
1、synchronized 關鍵字
可用來給對象和方法或者代碼塊加鎖,當它鎖定一個方法或者一個代碼塊的時候,同一時刻最多隻有一個線程執行這段代碼。可能鎖對象包括: this, 臨界資源對象,Class 類對象
2、同步方法
同步方法鎖定的是當前對象。當多線程通過同一個對象引用多次調用當前同步方法時, 需同步執行。
3、同步代碼塊
同步代碼塊的同步粒度更加細致,是商業開發中推薦的編程方式。可以定位到具體的同步位置,而不是簡單的將方法整體實現同步邏輯。在效率上,相對更高。
A)鎖定臨界對象
同步代碼塊在執行時,是鎖定 object 對象。當多個線程調用同一個方法時,鎖定對象不變的情況下,需同步執行。
B)鎖定當前對象
4、鎖的底層實現
Java 虛擬機中的同步(Synchronization)基於進入和退出管程(Monitor)對象實現。同步方法 並不是由 monitor enter 和 monitor exit 指令來實現同步的,而是由方法調用指令讀取運行時常量池中方法的 ACC_SYNCHRONIZED 標志來隱式實現的。
5、鎖的種類
Java 中鎖的種類大致分為偏向鎖,自旋鎖,輕量級鎖,重量級鎖。
鎖的使用方式為:先提供偏向鎖,如果不滿足的時候,升級為輕量級鎖,再不滿足,升級為重量級鎖。自旋鎖是一個過渡的鎖狀態,不是一種實際的鎖類型。
鎖只能升級,不能降級。
6、volatile 關鍵字
變數的線程可見性。在 CPU 計算過程中,會將計算過程需要的數據載入到 CPU 計算緩存中,當 CPU 計算中斷時,有可能刷新緩存,重新讀取內存中的數據。在線程運行的過程中,如果某變數被其他線程修改,可能造成數據不一致的情況,從而導致結果錯誤。而 volatile 修飾的變數是線程可見的,當 JVM 解釋 volatile 修飾的變數時,會通知 CPU,在計算過程中, 每次使用變數參與計算時,都會檢查內存中的數據是否發生變化,而不是一直使用 CPU 緩存中的數據,可以保證計算結果的正確。
更多、此外還有很多細節需要通過學習去了解和完善,此處就不一一列舉了。
二、並發框架
並發框架很多,如ExecutorService、RxJava、Disruptor、Akka等,具體選擇哪個(或者都不選擇)是根據項目需求選擇的,框架本身的差異並不大,基本都是如下模式
3. java中什麼是並發,如何解決
多個進程或線程同時(或著說在同一段時間內)訪問同一資源會產生並發問題。 銀行兩操作員同時操作同一賬戶就是典型的例子。比如A、B操作員同時讀取一餘額為1000元的賬戶,A操作員為該賬戶增加100元,B操作員同時為該賬戶減去
50元,A先提交,B後提交。 最後實際賬戶余額為1000-50=950元,但本該為 1000+100-50=1050。這就是典型的並發問題。
可以用鎖解決。
關於鎖我也不是太清楚,你可以研究一下.....
4. Java如何處理大量的並發請求
在web應用中,同一時間有大量的客戶端請求同時發送到伺服器,例如搶購、秒殺等。這個時候如何避免將大量的請求同時發送到業務系統。
第一種方法:在容器中配置最大請求數,如果大於改請求數,則客戶端阻塞。該方法有效的阻止了大量的請求同時訪問業務系統,但對用於不友好。
第二種方法:使用過濾器,保證一定數量的請求能夠正常訪問系統,多餘的請求先跳轉到排隊頁面,由排隊頁面定時發起請求。過濾器實現如下:
<pre name="code" class="java">public class ServiceFilter implements Filter { private static final int MAX_COUNT = 20; private int filterCount = 0; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("before"+filterCount); if(filterCount > MAX_COUNT) { //請求個數太多,跳轉到排隊頁面 request.getRequestDispatcher("index.jsp").forward(request, response); } else { //請求個數加1 filterCount ++; chain.doFilter(request, response); //訪問結束,請求個數減1 filterCount --; } }
}
5. 濡備綍澶勭悊java楂樺苟鍙戦棶棰
濡備綍澶勭悊騫跺彂鍜屽悓姝
浠婂ぉ璁茬殑濡備綍澶勭悊騫跺彂鍜屽悓鍚屾ラ棶棰樹富瑕佹槸閫氳繃閿佹満鍒躲
鎴戜滑闇瑕佹槑鐧斤紝閿佹満鍒舵湁涓や釜灞傞潰銆
涓縐嶆槸浠g爜灞傛′笂鐨勶紝濡俲ava涓鐨勫悓姝ラ攣錛屽吀鍨嬬殑灝辨槸鍚屾ュ叧閿瀛梥ynchronized錛岃繖閲屾垜涓嶅湪鍋氳繃澶氱殑璁茶В錛
鎰熷叴瓚g殑鍙浠ュ弬鑰:http://www.cnblogs.com/xiohao/p/4151408.html
鍙﹀栦竴縐嶆槸鏁版嵁搴撳眰嬈′笂鐨勶紝姣旇緝鍏稿瀷鐨勫氨鏄鎮茶傞攣鍜屼箰瑙傞攣銆傝繖閲屾垜浠閲嶇偣璁茶В鐨勫氨鏄鎮茶傞攣錛堜紶緇熺殑鐗╃悊閿侊級鍜屼箰瑙傞攣銆
鎮茶傞攣(Pessimistic Locking):
鎮茶傞攣錛屾e傚叾鍚嶏紝瀹冩寚鐨勬槸瀵規暟鎹琚澶栫晫錛堝寘鎷鏈緋葷粺褰撳墠鐨勫叾浠栦簨鍔★紝浠ュ強鏉ヨ嚜 澶栭儴緋葷粺鐨勪簨鍔″勭悊錛変慨鏀規寔淇濆畧鎬佸害錛屽洜姝わ紝
鍦ㄦ暣涓鏁版嵁澶勭悊榪囩▼涓錛屽皢鏁版嵁澶勪簬閿佸畾鐘舵併
鎮茶傞攣鐨勫疄鐜幫紝寰寰渚濋潬鏁版嵁搴撴彁渚涚殑閿佹満鍒訛紙涔熷彧鏈夋暟鎹搴撳眰鎻愪緵鐨勯攣鏈哄埗鎵嶈兘 鐪熸d繚璇佹暟鎹璁塊棶鐨勬帓浠栨э紝鍚﹀垯錛屽嵆浣垮湪鏈緋葷粺
涓瀹炵幇浜嗗姞閿佹満鍒訛紝涔熸棤娉曚繚璇佸栭儴緋 緇熶笉浼氫慨鏀規暟鎹錛夈
涓涓鍏稿瀷鐨勫氳禆鏁版嵁搴撶殑鎮茶傞攣璋冪敤錛
select * from account where name=鈥滶rica鈥 for update
榪欐潯 sql 璇鍙ラ攣瀹氫簡 account 琛ㄤ腑鎵鏈夌﹀悎媯緔㈡潯浠訛紙 name=鈥滶rica鈥 錛夌殑璁板綍銆
鏈嬈′簨鍔℃彁浜や箣鍓嶏紙浜嬪姟鎻愪氦鏃朵細閲婃斁浜嬪姟榪囩▼涓鐨勯攣錛夛紝澶栫晫鏃犳硶淇鏀硅繖浜涜板綍銆
Hibernate 鐨勬偛瑙傞攣錛屼篃鏄鍩轟簬鏁版嵁搴撶殑閿佹満鍒跺疄鐜般
涓嬮潰鐨勪唬鐮佸疄鐜頒簡瀵規煡璇㈣板綍鐨勫姞閿侊細
String hqlStr ="from TUser as user where user.name='Erica'";
Query query = session.createQuery(hqlStr);
query.setLockMode("user",LockMode.UPGRADE); // 鍔犻攣
List userList = query.list();// 鎵ц屾煡璇錛岃幏鍙栨暟鎹
query.setLockMode 瀵規煡璇㈣鍙ヤ腑錛岀壒瀹氬埆鍚嶆墍瀵瑰簲鐨勮板綍榪涜屽姞閿侊紙鎴戜滑涓 TUser 綾繪寚瀹氫簡涓涓鍒鍚 鈥渦ser鈥 錛夛紝榪欓噷涔熷氨鏄瀵
榪斿洖鐨勬墍鏈 user 璁板綍榪涜屽姞閿併
瑙傚療榪愯屾湡 Hibernate 鐢熸垚鐨 SQL 璇鍙ワ細
select tuser0_.id as id, tuser0_.name as name, tuser0_.group_id
as group_id, tuser0_.user_type as user_type, tuser0_.sex as sex
from t_user tuser0_ where (tuser0_.name='Erica' ) for update
榪欓噷 Hibernate 閫氳繃浣跨敤鏁版嵁搴撶殑 for update 瀛愬彞瀹炵幇浜嗘偛瑙傞攣鏈哄埗銆
Hibernate 鐨勫姞閿佹ā寮忔湁錛
Ø LockMode.NONE 錛 鏃犻攣鏈哄埗銆
Ø LockMode.WRITE 錛 Hibernate 鍦 Insert 鍜 Update 璁板綍鐨勬椂鍊欎細鑷鍔ㄨ幏鍙
Ø LockMode.READ 錛 Hibernate 鍦ㄨ誨彇璁板綍鐨勬椂鍊欎細鑷鍔ㄨ幏鍙栥
浠ヤ笂榪欎笁縐嶉攣鏈哄埗涓鑸鐢 Hibernate 鍐呴儴浣跨敤錛屽 Hibernate 涓轟簡淇濊瘉 Update
榪囩▼涓瀵硅薄涓嶄細琚澶栫晫淇鏀癸紝浼氬湪 save 鏂規硶瀹炵幇涓鑷鍔ㄤ負鐩鏍囧硅薄鍔犱笂 WRITE 閿併
Ø LockMode.UPGRADE 錛氬埄鐢ㄦ暟鎹搴撶殑 for update 瀛愬彞鍔犻攣銆
Ø LockMode. UPGRADE_NOWAIT 錛 Oracle 鐨勭壒瀹氬疄鐜幫紝鍒╃敤 Oracle 鐨 for
update nowait 瀛愬彞瀹炵幇鍔犻攣銆
涓婇潰榪欎袱縐嶉攣鏈哄埗鏄鎴戜滑鍦ㄥ簲鐢ㄥ眰杈冧負甯哥敤鐨勶紝鍔犻攣涓鑸閫氳繃浠ヤ笅鏂規硶瀹炵幇錛
Criteria.setLockMode
Query.setLockMode
Session.lock