当前位置:网站首页>避免list的并发修改异常的几种方式
避免list的并发修改异常的几种方式
2022-06-11 07:47:00 【tinyvampirepudge】
避免list的并发修改异常的几种方式
1、使用list的snapshot,遍历它的副本
使用如下:com.bumptech.glide.manager.ActivityFragmentLifecycle#onStart()
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
具体实现如下:
com.bumptech.glide.util.Util:
/**
* Returns a copy of the given list that is safe to iterate over and perform actions that may
* modify the original list.
*
* <p>See #303, #375, #322, #2262.
*/
@NonNull
@SuppressWarnings("UseBulkOperation")
public static <T> List<T> getSnapshot(@NonNull Collection<T> other) {
// toArray creates a new ArrayList internally and does not guarantee that the values it contains
// are non-null. Collections.addAll in ArrayList uses toArray internally and therefore also
// doesn't guarantee that entries are non-null. WeakHashMap's iterator does avoid returning null
// and is therefore safe to use. See #322, #2262.
List<T> result = new ArrayList<>(other.size());
for (T item : other) {
if (item != null) {
result.add(item);
}
}
return result;
}
2、使用CopyOnWriteArrayList
具体可以参考给ViewTreeObserver添加OnGlobalLayoutListener:
// Non-recursive listeners use CopyOnWriteArray
// Any listener invoked from ViewRootImpl.performTraversals() should not be recursive
@UnsupportedAppUsage
private CopyOnWriteArray<OnGlobalLayoutListener> mOnGlobalLayoutListeners;
/**
* Register a callback to be invoked when the global layout state or the visibility of views
* within the view tree changes
*
* @param listener The callback to add
*
* @throws IllegalStateException If {@link #isAlive()} returns false
*/
public void addOnGlobalLayoutListener(OnGlobalLayoutListener listener) {
checkIsAlive();
if (mOnGlobalLayoutListeners == null) {
mOnGlobalLayoutListeners = new CopyOnWriteArray<OnGlobalLayoutListener>();
}
mOnGlobalLayoutListeners.add(listener);
}
/**
* Remove a previously installed global layout callback
*
* @param victim The callback to remove
*
* @throws IllegalStateException If {@link #isAlive()} returns false
*
* @see #addOnGlobalLayoutListener(OnGlobalLayoutListener)
*/
public void removeOnGlobalLayoutListener(OnGlobalLayoutListener victim) {
checkIsAlive();
if (mOnGlobalLayoutListeners == null) {
return;
}
mOnGlobalLayoutListeners.remove(victim);
}
/**
* Notifies registered listeners that a global layout happened. This can be called
* manually if you are forcing a layout on a View or a hierarchy of Views that are
* not attached to a Window or in the GONE state.
*/
public final void dispatchOnGlobalLayout() {
// NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
// perform the dispatching. The iterator is a safe guard against listeners that
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
final CopyOnWriteArray<OnGlobalLayoutListener> listeners = mOnGlobalLayoutListeners;
if (listeners != null && listeners.size() > 0) {
CopyOnWriteArray.Access<OnGlobalLayoutListener> access = listeners.start();
try {
int count = access.size();
for (int i = 0; i < count; i++) {
access.get(i).onGlobalLayout();
}
} finally {
listeners.end();
}
}
}
/**addOnGlobalLayoutListener
* Register a callback to be invoked when the global layout state or the visibility of views
* within the view tree changes
*
* @param listener The callback to add
*
* @throws IllegalStateException If {@link #isAlive()} returns false
*/
public void addOnGlobalLayoutListener(OnGlobalLayoutListener listener) {
checkIsAlive();
if (mOnGlobalLayoutListeners == null) {
mOnGlobalLayoutListeners = new CopyOnWriteArray<OnGlobalLayoutListener>();
}
mOnGlobalLayoutListeners.add(listener);
}
/**
* Notifies registered listeners that a global layout happened. This can be called
* manually if you are forcing a layout on a View or a hierarchy of Views that are
* not attached to a Window or in the GONE state.
*/
public final void dispatchOnGlobalLayout() {
// NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
// perform the dispatching. The iterator is a safe guard against listeners that
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
final CopyOnWriteArray<OnGlobalLayoutListener> listeners = mOnGlobalLayoutListeners;
if (listeners != null && listeners.size() > 0) {
CopyOnWriteArray.Access<OnGlobalLayoutListener> access = listeners.start();
try {
int count = access.size();
for (int i = 0; i < count; i++) {
access.get(i).onGlobalLayout();
}
} finally {
listeners.end();
}
}
}
边栏推荐
- Opencv for face recognition
- Xshell7 和 Xftp7要继续使用此程序,您必须应用最新的更新或者使用新版本
- 【CodeForces908H】New Year and Boolean Bridges (FWT)
- C language function stack frame
- Qunhui ds918 creates m.2 SSD read / write cache
- Sort - Swap sort
- Methods to improve training speed in deep learning and techniques to reduce video memory (suitable for entry-level trick without too many computing resources)
- [codeforces1019e] raining season
- About static keyword
- What exactly is PMP?
猜你喜欢

零基础自学SQL课程 | OUTER JOIN外连接
![20200727 T2 small w playing game [generating function (binomial inversion technique)]](/img/a5/ae2192f4f37232cdcb01e81ad0297c.jpg)
20200727 T2 small w playing game [generating function (binomial inversion technique)]

TiDB Cloud 上线 Google Cloud Marketplace,以全新一栈式实时 HTAP 数据库赋能全球开发者

Detailed explanation of shift operator and bit operator in C language
![20200730 T3 small B farm [maximum perimeter empty rectangle (monotone stack + line segment tree)] &](/img/90/99356e679a52890a0b88068d082bbe.jpg)
20200730 T3 small B farm [maximum perimeter empty rectangle (monotone stack + line segment tree)] & "ROI 2017 day 2" learning track
![[codeforces1019e] raining season](/img/8e/4a96954ee7dae5f81eaae05b5a075b.png)
[codeforces1019e] raining season

About static keyword

Simple configuration of vscade

Alchemy experience (model training of deep learning) the necessity of timely adjusting training parameters for some situations (the adjustment of learning rate LR is the primary) summarizes some metho

2021-11-05 definition of cache
随机推荐
A detailed explanation of one of the causes of dead loop caused by array out of bounds in C language
[poj3691] DNA repair (AC automata +dp)
TiDB Cloud 上线 Google Cloud Marketplace,以全新一栈式实时 HTAP 数据库赋能全球开发者
测试4年裸辞失业,面试15k的测试岗被按在地上摩擦,结局让我崩溃大哭...
TiDB Cloud 上線 Google Cloud Marketplace,以全新一棧式實時 HTAP 數據庫賦能全球開發者
2. Graduated from this course, and the bank has outsourced testing work for more than 4 months. Talk about some real feelings
【AtCoder2304】Cleaning
Simple use of string
【AtCoder2304】Cleaning
Implementation of stack (C language)
【软件测试】这样的简历已经刷掉了90%的面试者
Methods to improve training speed in deep learning and techniques to reduce video memory (suitable for entry-level trick without too many computing resources)
Deux diplômés, la Banque a externalisé le travail d'essai pendant plus de quatre mois. Parler de vrais sentiments...
图数据库无缝集成Tushare接口
【集群】haproxy负载均衡
2022.6.7 特长生模拟
2021-10-24
Opencv for face recognition
[atcoder2306] rearranging (topology)
Alchemy experience (model training of deep learning) the necessity of timely adjusting training parameters for some situations (the adjustment of learning rate LR is the primary) summarizes some metho