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

歡迎訪問 生活随笔!

生活随笔

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

java

Java EE陷阱#1:忽略@Singleton的默认锁定

發布時間:2023/12/3 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java EE陷阱#1:忽略@Singleton的默认锁定 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

EJB Singleton Bean是EJB 3.1規范引入的,通常用于存儲緩存的數據。 這意味著,我們嘗試通過使用Singleton來提高應用程序的性能。 總的來說,這很好。 特別是在并行調用不多的情況下。 但是,如果我們忽略默認鎖,并且并行調用的數量增加,它就會改變。

合理的默認值

讓我們從一些Java代碼開始,看看如何合理設置鎖。 以下代碼片段顯示了一個簡單的帶有計數器和兩個方法的EJB Singleton。 method1將計數器的當前值寫入日志,method2的計數從0到100。

@Singleton @Remote(SingletonRemote.class) public class DefaultLock implements SingletonRemote {Logger logger = Logger.getLogger(DefaultLock.class.getName());private int counter = 0;@Overridepublic void method1() {this.logger.info("method1: " + counter);}@Overridepublic void method2() throws Exception {this.logger.info("start method2");for (int i = 0; i < 100; i++) {counter++;logger.info("" + counter);}this.logger.info("end method2");} }

如您所見,沒有定義鎖。 如果我們同時調用兩個方法,您希望在日志文件中看到什么?

2014-06-24 21:18:51,948 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 5) method1: 0 2014-06-24 21:18:51,949 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) start method2 2014-06-24 21:18:51,949 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 1 2014-06-24 21:18:51,949 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 2 2014-06-24 21:18:51,950 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 3... 2014-06-24 21:18:51,977 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 99 2014-06-24 21:18:51,977 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 100 2014-06-24 21:18:51,978 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) end method2 2014-06-24 21:18:51,978 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 6) method1: 100 2014-06-24 21:18:51,981 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 7) method1: 100 2014-06-24 21:18:51,985 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 8) method1: 100 2014-06-24 21:18:51,988 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 9) method1: 100

好的,這可能有點意外,默認是整個Singleton上的容器管理的寫鎖定。 這是一個很好的默認設置,以避免同時修改屬性。 但是,如果我們要執行只讀操作,那么這是一個糟糕的默認設置。 在這種情況下,方法調用的序列化將導致高負載下較低的可伸縮性和較低的性能。

如何避免呢?

這個問題的答案很明顯,我們需要注意并發管理。 和Java EE中一樣,有兩種方法可以處理它。 我們可以自己做,也可以要求容器做。

Bean托管并發

我不想過多地討論Bean管理的并發性。 這是管理并發訪問的最靈活的方法。 容器允許并發訪問Singleton的所有方法,并且您必須根據需要保護其狀態。 這可以通過使用sync和volatile來完成。 但是要小心,很多時候這并不像看起來那樣容易。

容器管理并發

容器托管并發性更易于使用,但不如Bean托管方法靈活。 但是根據我的經驗,對于一般用例來說已經足夠了。

正如我們在日志中看到的那樣,容器管理的并發性是EJB Singleton的默認值。 容器為整個Singleton設置寫鎖定,并序列化所有方法調用。

我們可以更改此行為,并在方法和/或類級別上定義讀寫鎖。 這可以通過使用@ javax.ejb.Lock(javax.ejb.LockType)注釋Singleton類或方法來完成。 LockType枚舉提供值WRITE和READ來定義互斥寫鎖定或讀鎖定。

以下代碼片段顯示了如何將method1和method2的Lock設置為LockType.READ 。

@Singleton @Remote(SingletonRemote.class) public class ReadLock implements SingletonRemote {Logger logger = Logger.getLogger(ReadLock.class.getName());private int counter = 0;@Override@Lock(LockType.READ)public void method1() {this.logger.info("method1: " + counter);}@Override@Lock(LockType.READ)public void method2() throws Exception {this.logger.info("start method2");for (int i = 0; i < 100; i++) {counter++;logger.info("" + counter);}this.logger.info("end method2");} }

如前所述,我們可以通過使用@Lock(LockType.READ)注釋類而不是同時使用這兩種方法來實現相同的目的。

好的,如果一切都按預期進行,則應該并行訪問這兩種方法。 因此,讓我們看一下日志文件。

2014-06-24 21:47:13,290 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 10) method1: 0 2014-06-24 21:47:13,291 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) start method2 2014-06-24 21:47:13,291 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 1 2014-06-24 21:47:13,291 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 2 2014-06-24 21:47:13,291 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 3... 2014-06-24 21:47:13,306 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 68 2014-06-24 21:47:13,307 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 69 2014-06-24 21:47:13,308 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 3) method1: 69 2014-06-24 21:47:13,310 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 70 2014-06-24 21:47:13,310 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 71... 2014-06-24 21:47:13,311 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 76 2014-06-24 21:47:13,311 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 77 2014-06-24 21:47:13,312 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 2) method1: 77 2014-06-24 21:47:13,312 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 78 2014-06-24 21:47:13,312 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 79... 2014-06-24 21:47:13,313 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 83 2014-06-24 21:47:13,313 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 84 2014-06-24 21:47:13,314 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 5) method1: 84 2014-06-24 21:47:13,316 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 85 2014-06-24 21:47:13,316 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 86 2014-06-24 21:47:13,317 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 87 2014-06-24 21:47:13,318 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 88 2014-06-24 21:47:13,318 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 6) method1: 89 2014-06-24 21:47:13,318 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 89 2014-06-24 21:47:13,319 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 90... 2014-06-24 21:47:13,321 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 99 2014-06-24 21:47:13,321 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 100 2014-06-24 21:47:13,321 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) end method2

結論

在本文開頭,我們發現Java EE使用容器管理的寫鎖作為默認值。 這導致所有方法調用的序列化處理,并降低了應用程序的可伸縮性和性能。 在實現EJB Singleton時,我們需要牢記這一點。

我們看了兩個用于控制并發管理的現有選項:Bean管理的并發和容器管理的并發。

我們使用容器托管方法為單例的這兩種方法定義了一個讀鎖。 這不像bean管理的方法那樣靈活,但是它更容易使用,并且在大多數情況下足夠了。 我們只需要提供一個注釋,容器將處理其余的注釋。

翻譯自: https://www.javacodegeeks.com/2014/06/java-ee-pitfalls-1-ignore-the-default-lock-of-a-singleton.html

總結

以上是生活随笔為你收集整理的Java EE陷阱#1:忽略@Singleton的默认锁定的全部內容,希望文章能夠幫你解決所遇到的問題。

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