Elasticsearch開發(fā)AtomicArray使用示例探究
序
本文主要研究一下Elasticsearch的AtomicArray
AtomicArray
elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/util/concurrent/AtomicArray.java
public class AtomicArray<E> { private final AtomicReferenceArray<E> array; private volatile List<E> nonNullList; public AtomicArray(int size) { array = new AtomicReferenceArray<>(size); } /** * The size of the expected results, including potential null values. */ public int length() { return array.length(); } /** * Sets the element at position {@code i} to the given value. * * @param i the index * @param value the new value */ public void set(int i, E value) { array.set(i, value); if (nonNullList != null) { // read first, lighter, and most times it will be null... nonNullList = null; } } public final void setOnce(int i, E value) { if (array.compareAndSet(i, null, value) == false) { throw new IllegalStateException("index [" + i + "] has already been set"); } if (nonNullList != null) { // read first, lighter, and most times it will be null... nonNullList = null; } } /** * Gets the current value at position {@code i}. * * @param i the index * @return the current value */ public E get(int i) { return array.get(i); } /** * Returns the it as a non null list. */ public List<E> asList() { if (nonNullList == null) { if (array == null || array.length() == 0) { nonNullList = Collections.emptyList(); } else { List<E> list = new ArrayList<>(array.length()); for (int i = 0; i < array.length(); i++) { E e = array.get(i); if (e != null) { list.add(e); } } nonNullList = list; } } return nonNullList; } /** * Copies the content of the underlying atomic array to a normal one. */ public E[] toArray(E[] a) { if (a.length != array.length()) { throw new ElasticsearchGenerationException("AtomicArrays can only be copied to arrays of the same size"); } for (int i = 0; i < array.length(); i++) { a[i] = array.get(i); } return a; } }
AtomicArray封裝了AtomicReferenceArray并定義了nonNullList,提供了asList方法轉換為ArrayList;
而setOnce方法則使用了AtomicReferenceArray的compareAndSet方法來實現;
另外set及setOnce都會判斷nonNullList是否為null,不為null則重新設置為null
GroupedActionListener
elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/action/support/GroupedActionListener.java
public final class GroupedActionListener<T> implements ActionListener<T> { private final CountDown countDown; private final AtomicInteger pos = new AtomicInteger(); private final AtomicArray<T> results; private final ActionListener<Collection<T>> delegate; private final Collection<T> defaults; private final AtomicReference<Exception> failure = new AtomicReference<>(); /** * Creates a new listener * @param delegate the delegate listener * @param groupSize the group size */ public GroupedActionListener(ActionListener<Collection<T>> delegate, int groupSize, Collection<T> defaults) { results = new AtomicArray<>(groupSize); countDown = new CountDown(groupSize); this.delegate = delegate; this.defaults = defaults; } @Override public void onResponse(T element) { results.setOnce(pos.incrementAndGet() - 1, element); if (countDown.countDown()) { if (failure.get() != null) { delegate.onFailure(failure.get()); } else { List<T> collect = this.results.asList(); collect.addAll(defaults); delegate.onResponse(Collections.unmodifiableList(collect)); } } } @Override public void onFailure(Exception e) { if (failure.compareAndSet(null, e) == false) { failure.accumulateAndGet(e, (previous, current) -> { previous.addSuppressed(current); return previous; }); } if (countDown.countDown()) { delegate.onFailure(failure.get()); } } }
- GroupedActionListener的構造器根據groupSize創(chuàng)建了AtomicArray及CountDown
- onResponse方法會調用AtomicArray的setOnce方法來設置結果,之后判斷countDown是否都完成了,完成的話判斷是否有failure,有則回調delegate.onFailure,沒有failure則調用AtomicArray的asList方法獲取list形式的結果,最后回調delegate.onResponse
- onFailure方法會更新failure,如果compareAndSet失敗則使用accumulateAndGet來更新,之后判斷countDown是否都完成了,完成的話則回調delegate.onFailure
CountDown
elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/util/concurrent/CountDown.java
public final class CountDown { private final AtomicInteger countDown; private final int originalCount; public CountDown(int count) { if (count < 0) { throw new IllegalArgumentException("count must be greater or equal to 0 but was: " + count); } this.originalCount = count; this.countDown = new AtomicInteger(count); } /** * Decrements the count-down and returns <code>true</code> iff this call * reached zero otherwise <code>false</code> */ public boolean countDown() { assert originalCount > 0; for (;;) { final int current = countDown.get(); assert current >= 0; if (current == 0) { return false; } if (countDown.compareAndSet(current, current - 1)) { return current == 1; } } } /** * Fast forwards the count-down to zero and returns <code>true</code> iff * the count down reached zero with this fast forward call otherwise * <code>false</code> */ public boolean fastForward() { assert originalCount > 0; assert countDown.get() >= 0; return countDown.getAndSet(0) > 0; } /** * Returns <code>true</code> iff the count-down has reached zero. Otherwise <code>false</code> */ public boolean isCountedDown() { assert countDown.get() >= 0; return countDown.get() == 0; } }
CountDown是一個簡易線程安全非阻塞版的CountDownLatch,它提供了countDown方法使用compareAndSet來遞減值,同時返回countDown是否完成(countDown.get() == 0
);
另外還提供了isCountedDown來查詢countDown是否完成;還有fastForward方法用于將countDown直接設置為0
小結
- AtomicArray封裝了AtomicReferenceArray并定義了nonNullList,提供了asList方法轉換為ArrayList;而setOnce方法則使用了AtomicReferenceArray的compareAndSet方法來實現;
- 另外set及setOnce都會判斷nonNullList是否為null,不為null則重新設置為null
- GroupedActionListener的構造器根據groupSize創(chuàng)建了AtomicArray及CountDown;
- onResponse方法會調用AtomicArray的setOnce方法來設置結果,之后判斷countDown是否都完成了,完成的話判斷是否有failure,有則回調delegate.onFailure,沒有failure則調用AtomicArray的asList方法獲取list形式的結果,最后回調delegate.onResponse;
- onFailure方法會更新failure,如果compareAndSet失敗則使用accumulateAndGet來更新,之后判斷countDown是否都完成了,完成的話則回調delegate.onFailure
- CountDown是一個簡易線程安全非阻塞版的CountDownLatch,它提供了countDown方法使用compareAndSet來遞減值,同時返回countDown是否完成(
countDown.get() == 0
); - 另外還提供了isCountedDown來查詢countDown是否完成;還有fastForward方法用于將countDown直接設置為0
doc
以上就是Elasticsearch AtomicArray使用示例探究的詳細內容,更多關于Elasticsearch AtomicArray的資料請關注腳本之家其它相關文章!
相關文章
logback TimeBasedRollingPolicy按天生成日志源碼解析
這篇文章主要為大家介紹了logback TimeBasedRollingPolicy按天生成日志源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11Java通過百度地圖API獲取定位(普通IP定位)的方法教程
這篇文章主要介紹了Java通過百度地圖API獲取定位的方法教程,首先說明了實現這個功能的需求和初衷,然后詳細描述了利用百度地圖API實現這個功能的步驟,包括在百度地圖開放平臺的準備工作、學習官網API文檔、修改API的AK配置、Java代碼獲取定位等,需要的朋友可以參考下2024-11-11在Java和Java Web中放置圖片、視頻、音頻、圖像文件的方法
在Java軟件中放置圖片,通常涉及將圖片文件(如JPEG、PNG等)作為資源包含在我們的項目中,并在代碼中通過適當的方式引用這些資源,這可以通過多種方式實現,但最常見的是在Java桌面應用(如Swing或JavaFX)或Web應用(如Servlet/JSP)中2024-11-11Spring Boot 2.4 對多環(huán)境配置的支持更改示例代碼
這篇文章主要介紹了Spring Boot 2.4 對多環(huán)境配置的支持更改,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12idea創(chuàng)建包含多個springboot module的maven project的方法
這篇文章主要介紹了idea創(chuàng)建包含多個springboot module的maven project的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09