Tag: java.util.concurrent

Java线程在处理结束时变慢

我有一个Java程序,它接收一个包含文本文件列表的文本文件,并分别处理每一行。 为了加快处理速度,我使用带有24个线程的FixedThreadPool的ExecutorService来使用线程。 该机器有24个内核和48GB内存。 我正在处理的文本文件有250万行。 我发现,对于前230万行左右,CPU运行率很高,运行良好。 然而,超过某些点(大约在2.3行),性能退化,只使用了一个CPU,我的程序几乎停止了。 我调查了很多原因,确保关闭所有文件句柄,并增加提供给JVM的内存量。 但是,无论我改变什么,性能总是会降低到最后。 我甚至尝试过包含更少行的文本文件,并且在处理文件结束时性能再次下降。 除了标准的Java并发库之外,代码还使用Lucene库进行文本处理和分析。 当我没有线程化这个代码时,性能是恒定的,并且不会在最后退化。 我知道这是一个黑暗的镜头,很难描述发生了什么,但我想我会看到是否有人有任何想法可能会导致这种性能退化到底。 编辑 在我收到的评论之后,我在这里粘贴了一个堆栈跟踪。 如您所见,它看起来好像没有任何线程阻塞。 此外,在分析时,当事情变慢时,GC不是100%。 实际上,大多数时候CPU和GC的利用率都是0%,CPU偶尔会出现一些文件,然后再次停止。 执行线程的代码 BufferedReader read = new BufferedReader(new FileReader(inputFile)); ExecutorService executor = Executors.newFixedThreadPool(NTHREADS); String line; while ((line = read.readLine()) != null) { //index each line Runnable worker = new CharikarHashThreader(line, bits, minTokens); executor.execute(worker); } read.close();

拥有单个线程池比多个线程池更好的设计

在Java中拥有多个线程池有什么优缺点? 我已经看到代码中有多个线程池用于不同的“类型”任务,我不确定它是更好的设计还是只是开发人员是懒惰的。 一个示例是将ScheduledThreadPoolExecutor用于定期执行或超时的任务,并使用另一个ThreadPoolExecutor执行其他任务。

为什么Lock条件等待必须持有锁

我对此表示怀疑,在Java语言中,我们需要保持锁定,然后再等待满足某些条件。 例如,int java monitor lock: synchronized(lock){ System.out.println(“before lock …”); lock.wait(); System.out.println(“after lock …”); } 或者是黄色的工具。 Lock lock = new ReentrantLock(); Condition cond = lock.newCondition(); lock.lock(); try{ System.out.println(“before condition …”); cond.await(); System.out.println(“after condition …”); }catch(Exception e){ e.printStackTrace(); }finally{ lock.unlock(); } 所以,为什么我们不能等待,而不是锁定? 如果只是因为Java,其他语言的工作有所不同? 我希望你能在设计之后解释原因,但不仅仅是JAVA-SPEC的定义。

是否存在带有getAndWait()方法的HashMap? 例如BlockingConcurrentHashMap实现?

许multithreading可能会填充HashMap ,在某些情况下我需要等待(阻塞)直到HashMap中存在对象,例如: BlockingConcurrentHashMap map = new BlockingConcurrentHashMap(); Object x = map.getAndWait(key, 1000); //(object_to_get, max_delay_ms) 想知道这样的东西是否已经存在,我讨厌重新发明轮子。

java.util.concurrent.LinkedBlockingQueue中的奇怪代码

所有! 我在LinkedBlockingQueue中发现了奇怪的代码: private E dequeue() { // assert takeLock.isHeldByCurrentThread(); Node h = head; Node first = h.next; h.next = h; // help GC head = first; E x = first.item; first.item = null; return x; } 谁能解释为什么我们需要局部变量h? 它对GC有什么帮助?

Java ThreadPool用法

我正在尝试编写一个multithreadingWeb爬虫。 我的主入门类有以下代码: ExecutorService exec = Executors.newFixedThreadPool(numberOfCrawlers); while(true){ URL url = frontier.get(); if(url == null) return; exec.execute(new URLCrawler(this, url)); } URLCrawler获取指定的URL,解析HTML从中提取链接,并将看不见的链接安排回边界。 边界是未抓取的URL队列。 问题是如何编写get()方法。 如果队列为空,则应等待任何URLCrawler完成,然后再次尝试。 仅当队列为空且当前没有活动的URLCrawler时,它才应返回null。 我的第一个想法是使用AtomicInteger来计算当前工作URLCrawler的数量以及notifyAll()/ wait()调用的辅助对象。 开始时每个爬虫都会增加当前工作URLCrawler的数量,并在退出时递减它,并通知对象它已完成。 但我读到notify()/ notifyAll()和wait()是一些不赞成做线程通信的方法。 我应该在这个工作模式中使用什么? 它类似于M生产者和N个消费者,问题是如何应对生产者的厌倦。

需要简单解释“锁定条带化”如何与ConcurrentHashMap一起使用

根据Java Concurrency in Practice,第11.4.3章说: 锁定拆分有时可以扩展到一组变量独立对象的分区锁定,在这种情况下,它被称为锁定条带化。 例如,ConcurrentHashMap的实现使用一个包含16个锁的数组,每个锁保护1/16的散列桶; 铲斗N由锁定N mod 16保护。 我仍然有理解和可视化锁条纹和铲斗机制的问题。 有人可以用很好理解的话来解释这个:) 提前致谢。

java中Executor和ExecutorCompletionservice之间的区别

问题标题本身说明了java中Executors和ExecutorCompletionService类之间的区别是什么? 我是Threading的新手,所以如果任何人都可以用一段代码来解释,那将会有很大的帮助。

我可以使用ForkJoinPool的工作窃取行为来避免线程饥饿死锁吗?

如果池中的所有线程都在等待同一池中的排队任务完成,则在正常线程池中发生线程饥饿死锁 。 ForkJoinPool通过从join()调用中窃取其他线程的工作来避免这个问题,而不是简单地等待。 例如: private static class ForkableTask extends RecursiveTask { private final CyclicBarrier barrier; ForkableTask(CyclicBarrier barrier) { this.barrier = barrier; } @Override protected Integer compute() { try { barrier.await(); return 1; } catch (InterruptedException | BrokenBarrierException e) { throw new RuntimeException(e); } } } @Test public void testForkJoinPool() throws Exception { final int parallelism […]

ConcurrentHashMap jdk 8使用TreeNodes而不是List ..为什么?

嗨,我知道在JDK 8之前ConcurrentHashMap的工作方式。我也理解了代码:它非常模块化,不太难理解。 JDK 8中的ConcurrentHashMap代码与之前的实现相比发生了很大变化。 因为这个问题被归类为过于宽泛,我现在会尝试非常具体。 CHMv8使用TreeBin(RedBlackTree的变体)来存储桶而不是链表。 所以我的问题是在链表上使用TreeBin的主要优势是什么? 源代码在这里