标签: java.util.concurrent

同时合并列表 - CopyOnWriteArrayList 或 ConcurrentLinkedQueue 哪个更好?

支持有几个线程运行查询任务,每个线程都会返回一个list结果,哪种数据结构会更快地合并结果?

并发链接队列

基于链接节点的无界线程安全队列。该队列对元素进行 FIFO(先进先出)排序。队列的头部是在队列中停留时间最长的元素。队列的尾部是在队列中停留时间最短的元素。新元素插入到队列尾部,队列检索操作获取队列头部元素。当许多线程共享对公共集合的访问时,ConcurrentLinkedQueue 是一个合适的选择。与大多数其他并发集合实现一样,此类不允许使用 null 元素。 该实现采用了一种高效的“无等待”算法,该算法基于 Maged M. Michael 和 Michael L. Scott 的《简单、快速和实用的非阻塞和阻塞并发队列算法》中描述的算法。

写入数组列表时复制

顾名思义,CopyOnWriteArrayList 使用每个突变操作(例如添加或设置)创建底层 ArrayList 的副本。通常,CopyOnWriteArrayList 非常昂贵,因为它在每次写入操作时都涉及昂贵的数组复制,但如果您有一个迭代次数超过突变的列表,则它非常有效,例如您主要需要迭代 ArrayList 并且不要太频繁地修改它。

java concurrency multithreading java.util.concurrent copyonwritearraylist

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

理解java的同步集合

我正在阅读有关包装器实现的java官方文档,它们是集合中用于获取同步集合的静态方法,例如:List<Type> list = Collections.synchronizedList(new ArrayList<Type>()); ...
我不明白的事情如下(我引用自java文档):

以这种方式创建的集合与通常同步的集合(例如 Vector)一样是线程安全的。面对并发访问,用户在迭代返回的集合时必须手动同步它。原因是迭代是通过对集合的多次调用来完成的,必须将其组合成单个原子操作......

它如何能够是线程安全的,并且需要在迭代时手动同步?

java collections java.util.concurrent

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

为什么java中Semaphore类的acquireUninterruptically()方法不能按预期工作?

我有两个 Java 文件:

检查.java

import java.util.concurrent.Semaphore;
class Check
{
 public static void main(String[] args)
 {
  Semaphore s = new Semaphore(1);
  MyThread t1 = new MyThread("t1",s);
  MyThread t2 = new MyThread("t2",s);
  t1.start();
  t2.start();
  t2.interrupt();
 }
}
Run Code Online (Sandbox Code Playgroud)

MyThread.java

import java.util.concurrent.Semaphore;
class MyThread extends Thread
{
 Semaphore s;
 MyThread(String name, Semaphore s)
 {
  super(name);
  this.s=s;
 }
 public void run()
 {
  try
  {
        s.acquireUninterruptibly();
        for(int i=0; i<5; i++)
        {
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName()+"-"+i);
        }
        s.release();
  }
  catch(InterruptedException e){}
 }
}
Run Code Online (Sandbox Code Playgroud)

如果我注释掉语句“t2.interrupt()”,那么两个线程都可以正常执行。但如果我不评论该语句,那么线程 t2 根本不会执行。根据我对 acquireUninterruptically() 方法的理解,线程 t2 …

java multithreading semaphore java.util.concurrent

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

ConcurrentHashMap如何实现其线程安全的并发行为?

我一直在浏览java.util.concurrent包,并试图了解库提供给我们的内容.我遇到CopyOnWriteArrayListConcurrentHashMap上课并试图找到这些条款如何实现线程安全.因为CopyOnWriteArrayList它非常直观,只要有写操作,就可以通过创建底层数组的新副本来实现它们.但是,我无法理解如何ConcurrentHashMap实现线程安全,同时提供并发性?

编辑:如果有人能告诉我实施背后的概念就足够了.考虑到这一点,我可以深入研究源代码,从而帮助我以更好的方式和结构化的方式理解它.

java java.util.concurrent

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

Findbugs的可能误报?

请参阅以下代码段(剥离冗余部分以突出显示有问题的情况):

FindBugs抱怨" 方法不会释放所有路径上的锁定 ".这是误报吗?如果没有,如何解决这个问题?

  try{
      someLock.lock();
     //do something
    } finally{
      if (someLock.isLocked())
        someLock.unlock();
    }
Run Code Online (Sandbox Code Playgroud)

java findbugs java.util.concurrent

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

如何为声明为ThreadLocal的变量的多个副本保持一致性?

据我所知,ThreadLocal变量为每个线程维护一个单独的变量副本.保持多个副本的此变量本质上是一个共享变量.那么说变量值可以有多个副本是什么意思呢?如何保持一致性,以使副本的值不会失去同步?

java multithreading thread-safety thread-local java.util.concurrent

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

用java.util.concurrent点火并忘记

如何使用java.util.concurrency 实现" fire and forget "行为?我试过了:

ExecutorService executor = Executors.newSingleThreadExecutor();

public void push(Callable<Boolean> task) {
    Future<Boolean> future = executor.submit(task);
    future.get(timeout, timeoutUnit);
}
Run Code Online (Sandbox Code Playgroud)

但是get()阻止直到完成.该push()来电者是不感兴趣的任务的结果.

java java.util.concurrent fire-and-forget

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

重用worker实例来处理多个任务

我有一个Web测试应用程序(基于Selenium,但这在这里应该不重要),它连续执行了大量的测试用例.这需要几个小时才能完成,测试用例数量会增加,所以我想使用多个Web浏览器实例并行执行多个测试用例.测试用例彼此之间没有依赖关系.

非常简化它看起来像这样:

TestExecutor executor = new TestExecutor(new FirefoxDriver());
for (TestCase test: tests) {
    executor.execute(test);
    // use results here
}
Run Code Online (Sandbox Code Playgroud)

现在我不确切知道如何并行化这个.我可以轻松地创建几个连接到几个Web浏览器的TestExecutors作为Callables并使用Executors,CompletitionServices和其他好帮手类,但我该如何:

  • 一旦它准备好使用之前的TestCase,就将新的TestCase传递给TestExecutor?Callable中的call()方法不带参数,所以我可能必须在我的TestExecutor类中实现一些setNextTestCase()来实现这个我觉得不太好的.还有更好的选择吗?

  • 重用TestExecutor实例来执行下一个测试用例?由于每个TestExecutor实例都需要一个Web浏览器实例,因此如果我为每个测试用例创建一个新的TestExecutor,则需要很长时间来初始化它并导致许多窗口在屏幕上闪烁.

java concurrency java.util.concurrent

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

为什么fork连接任务在公共fork连接池线程之外执行?

我可以通过提供代码片段来解释我的问题:

public static void main(final String[] a) {
    Stream.of(1, 2, 3, 4).map(i -> ForkJoinPool.commonPool().submit(new RecursiveAction() {
        @Override
        protected void compute() {
            System.out.println(Thread.currentThread());
        }
    })).forEach(ForkJoinTask::join);
}
Run Code Online (Sandbox Code Playgroud)

在我的笔记本电脑上运行时,它有4个核心,这打印:

Thread[main,5,main]
Thread[ForkJoinPool.commonPool-worker-1,5,main]
Thread[main,5,main]
Thread[ForkJoinPool.commonPool-worker-1,5,main]
Run Code Online (Sandbox Code Playgroud)

为什么某些任务在主线程中运行,主线程是公共fork连接线程池之外的线程?

创建自定义fork join线程池时,不会发生这种情况:

public static void main(final String[] a) {
    final ForkJoinPool p = new ForkJoinPool(4);

    Stream.of(1, 2, 3, 4).map(index -> p.submit(new RecursiveAction() {
        @Override
        protected void compute() {
            System.out.println(Thread.currentThread());
        }
    })).forEach(ForkJoinTask::join);
}

Thread[ForkJoinPool-1-worker-1,5,main]
Thread[ForkJoinPool-1-worker-1,5,main]
Thread[ForkJoinPool-1-worker-1,5,main]
Thread[ForkJoinPool-1-worker-1,5,main]
Run Code Online (Sandbox Code Playgroud)

那么,换句话说,公共池有什么特别之处?提供这些知识,在公共池中执行长时间运行的任务是明智的还是不明智的想法?

java java.util.concurrent fork-join forkjoinpool

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

Java 8并行运行多个方法

我有2种方法,这些方法具有要同时运行的不同返回类型。这是我的代码:

public void method(int id) {
    final CompletableFuture<List<FooA>> fooACF = CompletableFuture.supplyAsync(() -> generateFooA(id));
    final CompletableFuture<List<FooB>> fooBCF = CompletableFuture.supplyAsync(() -> generateFooB(id));
    List<FooA> fooAs = fooACF.get();
    List<FooB> fooBs = fooBCF.get();
    //Do more processesing
}

public List<FooA> generateFooA(int id) {
    //code
}

public List<FooB> generateFooB(int id) {
    //code
}
Run Code Online (Sandbox Code Playgroud)

但是我不知道这两种方法是否都可以与上面的代码并行运行,或者我是否更好地说:

List<FooA> fooAs = generateFooA(id);
List<FooB> fooBs = generateFooB(id);
Run Code Online (Sandbox Code Playgroud)

如何正确使用可完成的期货才能并行运行这两种方法?

java concurrency java.util.concurrent java-8 completable-future

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