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

歡迎訪問 生活随笔!

生活随笔

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

java

java lambda使用_使用Java 8和Lambda简化ReadWriteLock

發布時間:2023/12/3 java 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java lambda使用_使用Java 8和Lambda简化ReadWriteLock 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java lambda使用

考慮到舊版Java代碼,無論您在哪里看,帶有lambda表達式的Java 8絕對可以提高質量和可讀性。 今天,讓我們看一下ReadWriteLock以及如何使它使用起來更簡單。 假設我們有一個稱為Buffer的類,它可以記住隊列中的最后幾條消息,對舊消息進行計數并丟棄。 實現非常簡單:

public class Buffer {private final int capacity;private final Deque<String> recent;private int discarded;public Buffer(int capacity) {this.capacity = capacity;this.recent = new ArrayDeque<>(capacity);}public void putItem(String item) {while (recent.size() >= capacity) {recent.removeFirst();++discarded;}recent.addLast(item);}public List<String> getRecent() {final ArrayList<String> result = new ArrayList<>();result.addAll(recent);return result;}public int getDiscardedCount() {return discarded;}public int getTotal() {return discarded + recent.size();}public void flush() {discarded += recent.size();recent.clear();}}

現在我們可以putItem() ,但是內部recent隊列將僅保留最后一個capacity元素。 但是,它也記住必須丟棄多少項以避免內存泄漏。 該類工作正常,但僅在單線程環境中有效。 我們使用不是線程安全的ArrayDeque和非同步的int 。 盡管對int讀寫是原子的,但不能保證更改在不同線程中可見。 同樣,即使我們將線程安全的BlockingDeque與AtomicInteger一起使用,我們仍然處于競爭狀態的危險中,因為這兩個變量彼此不同步。

一種方法是synchronize所有方法 ,但這似乎很嚴格。 此外,我們懷疑讀取的數量大大超過寫入的數量。 在這種情況下, ReadWriteLock是一個很好的選擇。 它實際上包括兩個鎖-一個用于讀取,一個用于寫入。 實際上,它們都為同一把鎖競爭,而同一把鎖可以同時由一個作者或多個讀者獲得。 因此,當沒有人在寫并且只有寫者偶爾阻塞所有讀者時,我們可以進行并發讀取。 使用synchronized將始終阻止所有其他對象,無論他們做什么。 ReadWriteLock的可悲部分是它引入了許多樣板。 您必須顯式打開一個鎖,并記住在finally塊中對其進行unlock() 。 我們的實現變得難以閱讀:

public class Buffer {private final int capacity;private final Deque<String> recent;private int discarded;private final Lock readLock;private final Lock writeLock;public Buffer(int capacity) {this.capacity = capacity;recent = new ArrayDeque<>(capacity);final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();readLock = rwLock.readLock();writeLock = rwLock.writeLock();}public void putItem(String item) {writeLock.lock();try {while (recent.size() >= capacity) {recent.removeFirst();++discarded;}recent.addLast(item);} finally {writeLock.unlock();}}public List<String> getRecent() {readLock.lock();try {final ArrayList<String> result = new ArrayList<>();result.addAll(recent);return result;} finally {readLock.unlock(); }public int getDiscardedCount() {readLock.lock();try {return discarded;} finally {readLock.unlock();}}public int getTotal() {readLock.lock();try {return discarded + recent.size();} finally {readLock.unlock();}}public void flush() {writeLock.lock();try {discarded += recent.size();recent.clear();} finally {writeLock.unlock();}}}

這是在8月8日之前完成的方式。有效,安全且丑陋。 但是,使用lambda表達式,我們可以將橫切關注點包裝在這樣的實用工具類中:

public class FunctionalReadWriteLock {private final Lock readLock;private final Lock writeLock;public FunctionalReadWriteLock() {this(new ReentrantReadWriteLock());}public FunctionalReadWriteLock(ReadWriteLock lock) {readLock = lock.readLock();writeLock = lock.writeLock();}public <T> T read(Supplier<T> block) {readLock.lock();try {return block.get();} finally {readLock.unlock();}}public void read(Runnable block) {readLock.lock();try {block.run();} finally {readLock.unlock();}}public <T> T write(Supplier<T> block) {writeLock.lock();try {return block.get();} finally {writeLock.unlock();} public void write(Runnable block) {writeLock.lock();try {block.run();} finally {writeLock.unlock();}}}

如您所見,我們包裝了ReadWriteLock并提供了一組可使用的實用程序方法。 原則上,我們希望傳遞一個Runnable或Supplier<T> (具有單個T get()方法的接口),并確保調用它時已被適當的鎖包圍。 我們可以編寫完全相同的包裝器類,而無需使用lambda,但是使用它們可以大大簡化客戶端代碼:

public class Buffer {private final int capacity;private final Deque<String> recent;private int discarded;private final FunctionalReadWriteLock guard;public Buffer(int capacity) {this.capacity = capacity;recent = new ArrayDeque<>(capacity);guard = new FunctionalReadWriteLock();}public void putItem(String item) {guard.write(() -> {while (recent.size() >= capacity) {recent.removeFirst();++discarded;}recent.addLast(item);});}public List<String> getRecent() {return guard.read(() -> {return recent.stream().collect(toList());});}public int getDiscardedCount() {return guard.read(() -> discarded);}public int getTotal() {return guard.read(() -> discarded + recent.size());}public void flush() {guard.write(() -> {discarded += recent.size();recent.clear();});}}

看看我們如何調用guard.read()和guard.write()傳遞應該受到保護的代碼段? 看起來很整潔。 順便說一句,您是否注意到我們如何使用stream()將任何集合轉換為任何其他集合(在這里: Deque into List stream() ? 現在,如果我們提取幾個內部方法,則可以使用方法引用來進一步簡化lambda:

public void flush() {guard.write(this::unsafeFlush); }private void unsafeFlush() {discarded += recent.size();recent.clear(); }public List<String> getRecent() {return guard.read(this::defensiveCopyOfRecent); }private List<String> defensiveCopyOfRecent() {return recent.stream().collect(toList()); }

這只是利用lambda表達式來改進現有代碼和庫的眾多方法之一。 我們真的很高興他們終于進入Java語言了,同時已經出現在其他數十種JVM語言中。

翻譯自: https://www.javacodegeeks.com/2014/03/simplifying-readwritelock-with-java-8-and-lambdas.html

java lambda使用

總結

以上是生活随笔為你收集整理的java lambda使用_使用Java 8和Lambda简化ReadWriteLock的全部內容,希望文章能夠幫你解決所遇到的問題。

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