日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java线程详解(13)-锁

發布時間:2025/3/21 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线程详解(13)-锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java線程:新特征-鎖(上)

? ? ? ? 在Java5中,專門提供了鎖對象,利用鎖可以方便的實現資源的封鎖,用來控制對競爭資源并發訪問的控制,這些內容主要集中在java.util.concurrent.locks包下面,里面有三個重要的接口Condition、Lock、ReadWriteLock。

  • Condition將Object監視器方法(wait、notify和?notifyAll)分解成截然不同的對象,以便通過將這些對象與任意Lock實現組合使用,為每個對象提供多個等待?set(wait-set)。??
  • Lock實現提供了比使用synchronized方法和語句可獲得的更廣泛的鎖定操作。??
  • ReadWriteLock維護了一對相關的鎖定,一個用于只讀操作,另一個用于寫入操作。??

????????舉個例子:

import?java.util.concurrent.ExecutorService;?? import?java.util.concurrent.Executors;?? import?java.util.concurrent.locks.Lock;?? import?java.util.concurrent.locks.ReentrantLock;??/**?*?Java線程:線程池-鎖?*/?? public?class?Test?{??public?static?void?main(String[]?args){??//創建并發訪問的賬戶??MyCount?myCount=new?MyCount("6215580000000000000",10000);??//創建一個鎖對象??Lock?lock=new?ReentrantLock();??//創建一個線程池??ExecutorService?pool?=?Executors.newCachedThreadPool();??//創建一些并發訪問用戶,一個信用卡,存的存,取的取??User?u1?=?new?User("張三",?myCount,?-4000,?lock);??User?u2?=?new?User("張三他爹",?myCount,?6000,?lock);??User?u3?=?new?User("張三他弟",?myCount,?-8000,?lock);??User?u4?=?new?User("張三",?myCount,?800,?lock);??//在線程池中執行各個用戶的操作??pool.execute(u1);??pool.execute(u2);??pool.execute(u3);??pool.execute(u4);??//關閉線程池??pool.shutdown();??}?? }?? //信用卡用戶?? class?User?implements?Runnable{??private?String?name;????????????????//用戶名??private?MyCount?myCount;????????//所要操作的賬戶??private?int?iocash;????????????????//操作的金額,當然有正負之分了??private?Lock?myLock;????????????????//執行操作所需的鎖對象??User(String?name,?MyCount?myCount,?int?iocash,?LockmyLock)?{??this.name?=?name;??this.myCount?=?myCount;??this.iocash?=?iocash;??this.myLock?=?myLock;??}??@Override??public?void?run()?{??//獲取鎖??myLock.lock();??//執行現金業務??System.out.println(name?+?"正在操作"?+?myCount?+"賬戶,金額為"?+?iocash?+",當前金額為"?+?myCount.getCash());??myCount.setCash(myCount.getCash()?+?iocash);??System.out.println(name?+?"操作"?+?myCount?+"賬戶成功,金額為"?+?iocash?+",當前金額為"?+?myCount.getCash());??//釋放鎖,否則別的線程沒有機會執行了??myLock.unlock();??}???? }?? //信用卡賬戶,可隨意透支?? class?MyCount?{??private?String?oid;????????//賬號??private?int?cash;????????????//賬戶余額??MyCount(String?oid,?int?cash)?{??this.oid?=?oid;??this.cash?=?cash;??}??public?String?getOid()?{??return?oid;??}??public?void?setOid(String?oid)?{??this.oid?=?oid;??}??public?int?getCash()?{??return?cash;??}??public?void?setCash(int?cash)?{??this.cash?=?cash;??}??@Override??public?String?toString()?{??return"MyCount{"?+??"oid='"?+?oid?+?'\''?+??",?cash="?+?cash?+??'}';??}?? }??


????????執行結果:

張三他爹正在操作MyCount{oid='6215580000000000000',?cash=10000}賬戶,金額為6000,當前金額為10000?? 張三他爹操作MyCount{oid='6215580000000000000',?cash=16000}賬戶成功,金額為6000,當前金額為16000?? 張三正在操作MyCount{oid='6215580000000000000',?cash=16000}賬戶,金額為800,當前金額為16000?? 張三操作MyCount{oid='6215580000000000000',cash=16800}賬戶成功,金額為800,當前金額為16800?? 張三正在操作MyCount{oid='6215580000000000000',?cash=16800}賬戶,金額為-4000,當前金額為16800?? 張三操作MyCount{oid='6215580000000000000',cash=12800}賬戶成功,金額為-4000,當前金額為12800?? 張三他弟正在操作MyCount{oid='6215580000000000000',?cash=12800}賬戶,金額為-8000,當前金額為12800?? 張三他弟操作MyCount{oid='6215580000000000000',?cash=4800}賬戶成功,金額為-8000,當前金額為4800??


????????從上面的輸出可以看到,利用鎖對象太方便了,比直接在某個不知情的對象上用鎖清晰多了。

????????但一定要注意的是,在獲取了鎖對象后,用完后應該盡快釋放鎖,以便別的等待該鎖的線程有機會去執行

?

Java線程:新特征-鎖(下)


????????在上面提到了Lock接口以及對象,使用它,很優雅的控制了競爭資源的安全訪問,但是這種鎖不區分讀寫,稱這種鎖為普通鎖。為了提高性能,Java提供了讀寫鎖,在讀的地方使用讀鎖,在寫的地方使用寫鎖,靈活控制,在一定程度上提高了程序的執行效率。

????????Java中讀寫鎖有個接口java.util.concurrent.locks.ReadWriteLock,也有具體的實現ReentrantReadWriteLock,詳細的API可以查看JavaAPI文檔。

????????下面這個例子是在文例子的基礎上,將普通鎖改為讀寫鎖,并添加賬戶余額查詢的功能,代碼如下:

import?java.util.concurrent.ExecutorService;?? import?java.util.concurrent.Executors;?? import?java.util.concurrent.locks.ReadWriteLock;?? import?java.util.concurrent.locks.ReentrantReadWriteLock;??/**?*?Java線程:線程池-鎖?*/?? public?class?Test?{??public?static?void?main(String[]?args){??//創建并發訪問的賬戶??MyCount?myCount=new?MyCount("6215580000000000000",10000);??//創建一個鎖對象??ReadWriteLock?lock=new?ReentrantReadWriteLock(false);??//創建一個線程池??ExecutorService?pool?=?Executors.newCachedThreadPool();??//創建一些并發訪問用戶,一個信用卡,存的存,取的取??User?u1?=?new?User("張三",?myCount,?-4000,?lock,?false);??User?u2?=?new?User("張三他爹",?myCount,?6000,?lock,?false);??User?u3?=?new?User("張三他弟",?myCount,?-8000,?lock,?false);??User?u4?=?new?User("張三",?myCount,?800,?lock,false);??User?u5?=?new?User("張三他爹",?myCount,?0,?lock,true);??//在線程池中執行各個用戶的操作??pool.execute(u1);??pool.execute(u2);??pool.execute(u3);??pool.execute(u4);??pool.execute(u5);??//關閉線程池??pool.shutdown();??}?? }?? //信用卡用戶?? class?User?implements?Runnable{??private?String?name;????????????????//用戶名??private?MyCount?myCount;????????//所要操作的賬戶??private?int?iocash;????????????????//操作的金額,當然有正負之分了??private?ReadWriteLock?myLock;????????????????//執行操作所需的鎖對象??private?boolean?ischeck;???????//是否查詢??User(String?name,?MyCount?myCount,?int?iocash,ReadWriteLock?myLock,boolean?ischeck)?{??this.name?=?name;??this.myCount?=?myCount;??this.iocash?=?iocash;??this.myLock?=?myLock;??this.ischeck?=?ischeck;?? }??@Override??public?void?run()?{??if?(ischeck)?{??//獲取讀鎖??myLock.readLock().lock();??System.out.println("讀:"?+?name?+"正在查詢"?+?myCount?+"賬戶,當前金額為"?+?myCount.getCash());??//釋放讀鎖??myLock.readLock().unlock();??}?else?{??//獲取寫鎖??myLock.writeLock().lock();??//執行現金業務??System.out.println("寫:"?+?name?+"正在操作"?+?myCount?+"賬戶,金額為"?+?iocash?+",當前金額為"?+?myCount.getCash());??myCount.setCash(myCount.getCash()?+?iocash);??System.out.println("寫:"?+?name?+"操作"?+?myCount?+"賬戶成功,金額為"?+?iocash?+",當前金額為"?+?myCount.getCash());??//釋放寫鎖??myLock.writeLock().unlock();??}??}???? }?? //信用卡賬戶,可隨意透支?? class?MyCount?{??private?String?oid;????????//賬號??private?int?cash;????????????//賬戶余額??MyCount(String?oid,?int?cash)?{??this.oid?=?oid;??this.cash?=?cash;??}??public?String?getOid()?{??return?oid;??}??public?void?setOid(String?oid)?{??this.oid?=?oid;??}??public?int?getCash()?{??return?cash;??}??public?void?setCash(int?cash)?{??this.cash?=?cash;??}??@Override??public?String?toString()?{??return"MyCount{"?+??"oid='"?+?oid?+?'\''?+??",cash="?+?cash?+??'}';??}?? }??


????????執行結果:

寫:張三他爹正在操作MyCount{oid='6215580000000000000',?cash=10000}賬戶,金額為6000,當前金額為10000?? 寫:張三他爹操作MyCount{oid='6215580000000000000',?cash=16000}賬戶成功,金額為6000,當前金額為16000?? 寫:張三正在操作MyCount{oid='6215580000000000000',?cash=16000}賬戶,金額為-4000,當前金額為16000?? 寫:張三操作MyCount{oid='6215580000000000000',?cash=12000}賬戶成功,金額為-4000,當前金額為12000?? 寫:張三他弟正在操作MyCount{oid='6215580000000000000',?cash=12000}賬戶,金額為-8000,當前金額為12000?? 寫:張三他弟操作MyCount{oid='6215580000000000000',?cash=4000}賬戶成功,金額為-8000,當前金額為4000?? 讀:張三他爹正在查詢MyCount{oid='6215580000000000000',?cash=4000}賬戶,當前金額為4000?? 寫:張三正在操作MyCount{oid='6215580000000000000',?cash=4000}賬戶,金額為800,當前金額為4000?? 寫:張三操作MyCount{oid='6215580000000000000',?cash=4800}賬戶成功,金額為800,當前金額為4800??


????????在實際開發中,最好在能用讀寫鎖的情況下使用讀寫鎖,而不要用普通鎖,以求更好的性能。
?

總結

以上是生活随笔為你收集整理的Java线程详解(13)-锁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。