Tag: java.util.concurrent

同步块可以比Atomics更快吗?

假设有以下两个计数器实现: class Counter { private final AtomicInteger atomic = new AtomicInteger(0); private int i = 0; public void incrementAtomic() { atomic.incrementAndGet(); } public synchronized void increment() { i++; } } 乍一看,primefaces应该更快,更具可扩展性。 我相信他们是。 但它们是否比synchronized块一样快? 或者当该规则被破坏时存在某些情况(例如SMP /单CPU机器,不同的CPU ISA,OS等)?

单线程处理任务而不排队进一步的请求

我要求异步执行任务,同时丢弃任何进一步的请求,直到任务完成。 同步方法只是将任务排队,不会跳过。 我最初想过使用SingleThreadExecutor,但也会排队任务。 然后我查看了ThreadPoolExecutor,但是它读取队列以获取要执行的任务,因此将执行一个任务并且至少有一个任务排队(其他任务可以使用ThreadPoolExecutor.DiscardPolicy丢弃)。 我唯一能想到的是使用信号量来阻止队列。 我来自以下示例来展示我正在努力实现的目标。 有更简单的方法吗? 我错过了一些明显的东西吗 import java.util.concurrent.*; public class ThreadPoolTester { private static ExecutorService executor = Executors.newSingleThreadExecutor(); private static Semaphore processEntry = new Semaphore(1); public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 20; i++) { kickOffEntry(i); Thread.sleep(200); } executor.shutdown(); } private static void kickOffEntry(final int […]

删除()后,ConcurrentLinkedQueue $ Node保留在堆中

我有一个multithreading应用程序编写和读取ConcurrentLinkedQueue,它在概念上用于支持列表/表中的条目。 我最初为此使用了ConcurrentHashMap,效果很好。 需要跟踪订单条目的新要求,因此可以在最早的第一个订单中删除它们,具体取决于某些条件。 ConcurrentLinkedQueue似乎是一个不错的选择,function上它运作良好。 可配置数量的条目保存在内存中,当达到限制时提供新条目时,将以最早的顺序搜索队列以查找可以删除的队列。 系统不会删除某些条目并等待客户端交互。 似乎正在发生的事情是我在队列的前面有一个条目,比如100K条目之前。 队列似乎具有有限数量的已配置条目(size()== 100),但在分析时,我发现内存中有~100K ConcurrentLinkedQueue $ Node对象。 这似乎是设计上的,只是浏览了ConcurrentLinkedQueue的源代码,删除只删除对存储对象的引用,但留下链接列表进行迭代。 最后我的问题是:是否有一种“更好”的懒惰方式来处理这种性质的集合? 我喜欢ConcurrentLinkedQueue的速度,我无法承受在这种情况下似乎可能出现的无界泄漏。 如果没有,似乎我必须创建第二个结构来跟踪订单,可能有相同的问题,加上同步问题。

什么时候CopyOnWriteArraySet有用来实现线程安全的HashSet?

在Java ,有一个名为ConcurrentHashMap的线程安全版HashMap和一个名为ConcurrentSkipListMap的线程安全版TreeMap ,但是HashSet没有ConcurrentHashSet 。 相反,通常有4种方法可以使用线程安全的Set : Set mySet = Collections.newSetFromMap(new ConcurrentHashMap()); Set s = Collections.synchronizedSet(new HashSet()); ConcurrentSkipListSet CopyOnWriteArraySet 1使用ConcurrentHashMap keySet()来实现Set和线程安全。 2使用synchronized方式,似乎不推荐这种方式。 3基于ConcurrentSkipListMap并被广泛使用。 4基于CopyOnWriteArrayList ,因此它共享CopyOnWriteArrayList的相同基本属性。 以下是从CopyOnWriteArraySet doc中选择的: http : //docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArraySet.html 它最适合于设置大小通常很小的应用程序,只读操作数量远远超过可变操作,并且您需要在遍历期间防止线程之间的干扰。 它是线程安全的。 变异操作(添加,设置,删除等)很昂贵,因为它们通常需要复制整个底层arrays。 迭代器不支持mutative remove操作。 遍历迭代器的速度很快,不会遇到来自其他线程的干扰。 迭代器在构造迭代器时依赖于不变的数组快照。 由于常用1和3,为什么CopyOnWriteArraySet存在? CopyOnWriteArraySet什么时候有用? 补充: CopyOnWriteArraySet基于CopyOnWriteArrayList ,而List数据结构中的contains操作是O(n),而Set数据结构是针对高性能contains操作的,有人可以解释一下吗?

在java中实现自己的阻塞队列

我知道这个问题之前已被多次询问和回答,但我无法弄清楚互联网上的例子,比如这个或那个 。 这两个解决方案都检查阻塞队列的数组/队列/链表的空白,以便在get()方法中通知put()方法中的所有等待线程,反之亦然。 第二个链接中的评论强调了这种情况,并提到这不是必要的。 所以问题是; 检查队列是否为空,对我来说似乎有点奇怪 完全通知所有等待的线程。 有任何想法吗? 提前致谢。

Java ServiceExecutor终止条件

我是java执行器的新手。 我正在使用Java的ExecutorService来启动多个线程来处理数据。 Executor executor = Executors.newFixedThreadPool(poolSize); for(int i=0; i< 5;i++) executor.execute(new MyRunnable(i)); 一旦线程找不到数据,它们就会优雅地终止。 我的问题是当所有线程终止时,Executor会发生什么,它是否仍在运行其主线程? 或者它将自行终止,整个申请将优雅地完成? 如果执行程序线程仍然运行,我怎么能让它在所有子线程完成后终止(poolSize线程数)。

Future.cancel(true)下面发生了什么

假设我有一个Runnable实例: class MyTask implements Runnable { public void run() { //some heavy calculation which takes time Thread.sleep(5000) //rest code … } } 然后,我使用ExecutorService提交上述任务: ExecutorService service = Executors.newFixedThreadPool(3); Future task = service.submit(new MyTask()); 现在,我可以通过task.cancel(true);取消任务task.cancel(true); 。 我所理解的是task.cancel(true)将中断运行此任务的工作线程,如Thread.currentThread().interrupt() 。 但是这只会设置一个标志来告诉工作线程是否被中断。 我的问题是:如果MyTask Runnable已经开始运行, future.cancel(true)实际上是如何在run()停止执行其余代码的代码? 是否有定期检查下方工作线程的中断标志? 我的意思是我不明白如何只通过将interrupt标志设置为true来取消run()中的代码。

使用内部锁进入块

我没有看到下面的代码如何产生看起来违反对象锁定义的输出。 当然只允许一个线程打印“获取的锁定”消息,但他们都这样做? class InterruptThreadGroup { public static void main(String[] args) { Object lock = new Object(); MyThread mt1 = new MyThread(lock); MyThread mt2 = new MyThread(lock); mt1.setName(“A”); mt1.start(); mt2.setName(“B”); mt2.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { } // Thread.currentThread().getThreadGroup().interrupt(); } } class MyThread extends Thread { private Object lock; public MyThread(Object l) { […]

Java并发对象池?

我尝试将外部非线程安全库集成到我的Web项目中; 我发现为每个客户端线程创建此对象的实例太昂贵了。 因此,我想创建一个具有以下属性的对象池。 动态对象创建时,动态创建池中的对象,而不是在构造函数中创建它们。 池最初为空,当客户端线程获取资源对象时,池可以按需创建新资源。 一旦创建的对象的数量达到池的大小; 然后将阻止新的客户端线程,并等待其他线程回收资源。 池应该是公平的,公平性确保第一个要求的线程是获得的第一个线程; 否则有些线程可能会永远等待。 我该怎么做? 如果有一个有效的例子,我将不胜感激。

限制线程数和Java并发

我找不到使用最新JAVA并发例程的这种特定情况的示例。 我计划使用threads处理来自开放队列的项目,该队列可能包含0到数千个请求。 我想限制所以在任何给定的时间不少于0并且不超过10个线程处理队列项。 是否有针对此特定类型案例的Java并发流程?