标签: java.util.concurrent

从数组列表中删除元素后java.util.ConcurrentModificationException android

我在我的Android应用程序中有以下代码:

/**
 * callback executed after fetching the data.
 */
public void OnPointsFetch(ArrayList<Shop> result) {

    toggleLoader(false);

    this.shops = result;

    if(activeFilter == Constants.POINTS_FILTER_AVAILABLE){
        for(Shop s : result){
            if(s.getClientPoints().getPointsAvailable() == 0){
                this.shops.remove(s);
            }
        }
    }
    else{
        for(Shop s : result){
            if(s.getClientPoints().getPointsSpent() == 0){
                this.shops.remove(s);
            }   
        }
    }


    ptsListAdapter.setCollection(this.shops);
    ptsListAdapter.setFilter(this.activeFilter);

}
Run Code Online (Sandbox Code Playgroud)

在异步任务的结果上调用此方法.我需要在传递给列表适配器之前删除集合的一些元素.

    11-23 17:39:59.760: E/AndroidRuntime(19777): java.util.ConcurrentModificationException
11-23 17:39:59.760: E/AndroidRuntime(19777):    at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
Run Code Online (Sandbox Code Playgroud)

android exception arraylist java.util.concurrent

17
推荐指数
1
解决办法
2万
查看次数

ConcurrentHashMap中的entrySet().removeIf的行为

我想使用ConcurrentHashMap让一个线程定期从地图中删除一些项目,并使用其他线程同时从地图中放置和获取项目.

我正在使用map.entrySet().removeIf(lambda)删除线程.我想知道我可以对它的行为做出什么假设.我可以看到该removeIf方法使用迭代器来遍历地图中的元素,检查给定的条件,然后在需要时使用它们将其删除iterator.remove().

文档提供了有关ConcurrentHashMap迭代器行为的一些信息:

类似地,Iterators,Spliterators和Enumerations在迭代器/枚举的创建时或之后的某个时刻返回反映哈希表状态的元素.嘿不要抛出ConcurrentModificationException.但是,迭代器设计为一次只能由一个线程使用.

由于整个removeIf调用发生在一个线程中,我可以确定迭代器当时不被多个线程使用.我仍然想知道下面描述的事件是否可行:

  1. 地图包含映射: 'A'->0
  2. 删除线程开始执行 map.entrySet().removeIf(entry->entry.getValue()==0)
  3. 删除线程调用.iteratator()内部removeIf呼叫,并获得迭代器反映了收集的当前状态
  4. 另一个线程执行 map.put('A', 1)
  5. 删除线程仍然看到'A'->0映射(迭代器反映旧状态),因为0==0它是true,它决定从地图中删除A键.
  6. 地图现在包含'A'->1但删除线程看到旧值,0并且'A' ->1条目被删除,即使它不应该.地图是空的.

我可以想象,实施可以通过多种方式防止这种行为.例如:可能迭代器不反映put/remove操作,但总是反映值更新,或者迭代器的remove方法可能会检查整个映射(键和值)是否仍然存在于映射中,然后才调用键上的remove.我找不到任何有关这些事情的信息,我想知道是否有一些东西可以使用例安全.

java multithreading concurrenthashmap java.util.concurrent concurrentmodification

17
推荐指数
2
解决办法
6170
查看次数

在ReentrantReadWriteLock#tryLock失败时被jcstress测试困惑

我正试图掌握JCStress.为了确保我理解它,我决定为我知道必须正确的东西写一些简单的测试:java.util.concurrent.locks.ReentrantReadWriteLock.

我写了一些非常简单的测试来检查锁模式兼容性.不幸的是,有两项压力测试失败了:

  1. X_S:

    true, true        32,768     FORBIDDEN  No default case provided, assume FORBIDDEN
    
    Run Code Online (Sandbox Code Playgroud)
  2. X_X:

    true, true        32,767     FORBIDDEN  No default case provided, assume FORBIDDEN
    
    Run Code Online (Sandbox Code Playgroud)

在我看来,一个线程不应该能够保持读锁定,而另一个线程也保持写锁定.同样,两个线程不可能同时保持写锁定.

我意识到这个问题很可能没有ReentrantReadWriteLock.我想我可能在jcstress测试中犯了一些关于JMM和读取锁状态的愚蠢错误.

不幸的是,我无法发现问题.有人可以帮我理解我所犯的(愚蠢?)错误吗?

import org.openjdk.jcstress.annotations.*;
import org.openjdk.jcstress.infra.results.ZZ_Result;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/*
 * |-----------------|
 * |  COMPATIBILITY  |
 * |-----------------|
 * |     | S   | X   |
 * |-----------------|
 * | S   | YES | NO  |
 * | X   | NO  | NO  |
 * |-----------------|
 */
public class ReentrantReadWriteLockBooleanCompatibilityTest { …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading java.util.concurrent jcstress

17
推荐指数
1
解决办法
277
查看次数

如何"取消"CountDownLatch?

我有多个消费者线程在等待CountDownLatch1的大小使用await().我有一个生产者线程,countDown()当它成功完成时调用.

当没有错误时,这很有用.

但是,如果生产者检测到错误,我希望它能够将错误发送给消费者线程.理想情况下,我可以让生产者调用类似的东西abortCountDown(),让所有的消费者都收到InterruptedException或其他一些异常.我不想打电话countDown(),因为这需要我的所有消费者线程在他们打电话之后再做一次手动检查以获得成功await().我宁愿他们只是收到一个异常,他们已经知道如何处理.

我知道没有中止设施CountDownLatch.是否有另一个同步原语,我可以很容易地适应,有效地创建一个CountDownLatch支持中止倒计时?

java concurrency java.util.concurrent

16
推荐指数
2
解决办法
5910
查看次数

在尝试之前lock.lock()

之间有什么区别:

private Lock lock = new ReentrantLock(true);

public void getIn (int direction) throws InterruptedException {

     lock.lock();
     try {
         ...
Run Code Online (Sandbox Code Playgroud)

...

public void getIn (int direction) throws InterruptedException {

      try {
          lock.lock();
          ...
Run Code Online (Sandbox Code Playgroud)

编译顺利,程序也可以工作(我的意思是相同的输出)

我应该把lock.lock(); 在尝试之前或之后?...

谢谢你的帮助

java locking java.util.concurrent

16
推荐指数
4
解决办法
4061
查看次数

在java中是否存在BlockingMap作为BlockingQueue?

我想要一个与BlockingQueue非常相似的BlockingMap数据结构.BlockingQueue的take方法将在那里等待,直到元素可用.我希望BlockingMap的get方法在那里等待,直到相应的密钥可用?我可以使用这种数据结构吗?

java concurrency java.util.concurrent

16
推荐指数
2
解决办法
9912
查看次数

在java 8中从并行流中收集

我想获取输入并在其上应用并行流,然后我想输出为列表.输入可以是我们可以应用流的任何列表或任何集合.

我担心的是,如果我们想要输出作为映射它们,我们有一个来自java的选项就像

list.parallelStream().collect(Collectors.toConcurrentMap(args))
Run Code Online (Sandbox Code Playgroud)

但是我没有选择以线程安全的方式从并行流中收集以提供列表作为输出.我看到另外一个选项可供使用

list.parallelStream().collect(Collectors.toCollection(<Concurrent Implementation>))

通过这种方式,我们可以在collect方法中提供各种并发实现.但我认为java.util.concurrent中只存在CopyOnWriteArrayList List实现.我们可以在这里使用各种队列实现,但那些不会像列表一样.我的意思是我们可以解决这个问题.

如果我想要输出列表,你能指导一下最好的方法吗?

注意:我找不到与此相关的任何其他帖子,任何参考都会有所帮助.

java java.util.concurrent java-8 java-stream

16
推荐指数
2
解决办法
9636
查看次数

为什么ConcurrentSkipListSet升序迭代器比降序迭代器更快?

我在ConcurrentSkipListSet上使用了descendingIterator方法.我刚检查了文档并注意到以下注释:

'升序有序视图及其迭代器比下行视图更快.

请参阅https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentSkipListSet.html#descendingIterator--

不幸的是,它没有提供任何关于此的更多信息.有什么样的性能差异?它有意义吗?为什么会有性能差异?

java collections iterator java.util.concurrent

16
推荐指数
1
解决办法
241
查看次数

java中Executor和ExecutorCompletionservice之间的区别

问题标题本身说明了java中Executors和ExecutorCompletionService类之间的区别是什么?

我是Threading的新手,所以如果有人可以用一段代码来解释,那将会有很大帮助.

java multithreading java.util.concurrent

15
推荐指数
1
解决办法
5452
查看次数

如何使用AtomicBoolean阻止和等待

我正在寻找一种暂停线程的方法.

我开始有效地使用布尔标志(称为'暂停'),并使用while循环(暂停)包装检查.

在while循环中,有一个Thread.wait()阻止执行.

我一直在看AtomicBoolean,除了它不会阻止之外,它似乎可以解决这个问题.

是否有替代或扩展版本的AtomicBoolean有一个块方法?

即喜欢AtomicBoolean.getFalse()的东西AtomoicBoolean.get(false)

它们具有阻塞队列,因此具有阻塞值.

目前的设置是:

while (paused.get()) {
        synchronized (paused) {
            try {

                paused.wait();
            } catch (Exception e) {
            }

            paused.notify();
        }
    }
Run Code Online (Sandbox Code Playgroud)

public void pause() {
    if (paused.compareAndSet(false, true)) {
        synchronized (paused) {
            paused.notify();
        }
    }

}


public void resume() {
    if (paused.compareAndSet(true, false)) {
        synchronized (paused) {
            paused.notify();
        }
    } 
}
Run Code Online (Sandbox Code Playgroud)

java concurrency atomic java.util.concurrent

15
推荐指数
2
解决办法
2万
查看次数