Tag: 并发

在嵌套的Java 8并行流动作中使用信号量可能是DEADLOCK。 这是一个错误吗?

考虑以下情况:我们使用Java 8并行流来执行并行forEach循环,例如, IntStream.range(0,20).parallel().forEach(i -> { /* work done here */}) 并行线程的数量由系统属性“java.util.concurrent.ForkJoinPool.common.parallelism”控制,通常等于处理器的数量。 现在假设我们想限制特定工作的并行执行次数 – 例如,因为该部分是内存密集型的,而内存约束意味着并行执行的限制。 限制并行执行的一种明显而优雅的方法是使用信号量( 此处建议),例如,以下代码片段将并行执行的数量限制为5: final Semaphore concurrentExecutions = new Semaphore(5); IntStream.range(0,20).parallel().forEach(i -> { concurrentExecutions.acquireUninterruptibly(); try { /* WORK DONE HERE */ } finally { concurrentExecutions.release(); } }); 这很好用! 但是:在worker中使用任何其他并行流(在/* WORK DONE HERE */ )可能会导致死锁 。 对我来说,这是一个意外的行为。 说明:由于Java流使用ForkJoin池,因此内部forEach正在分叉,并且连接似乎正在等待。 但是,这种行为仍然出乎意料。 请注意,如果将”java.util.concurrent.ForkJoinPool.common.parallelism”设置为1,并行流甚至可以工作。 另请注意,如果存在内部并行forEach,则它可能不透明。 问题: 这种行为是否符合Java 8规范(在这种情况下,它意味着禁止在并行流工作者中使用信号量)或者这是一个错误? […]

通过具体(Java)示例进行乐观锁定

我早上花了很多时间阅读谷歌在乐观锁定方面所做的所有热门文章,而对于我的生活,我仍然没有真正理解。 我理解乐观锁定涉及添加用于跟踪记录的“版本”的列,并且该列可以是时间戳,计数器或任何其他版本跟踪构造。 但我仍然不明白如何确保WRITE完整性(意味着如果多个进程同时更新同一个实体,那么之后,实体正确地反映了它应该处于的真实状态)。 有人可以提供一个具体的,易于理解的例子,说明如何在Java中使用乐观锁定(可能是MySQL DB)。 假设我们有一个Person实体: public class Person { private String firstName; private String lastName; private int age; private Color favoriteColor; } 并且Person实例被持久化到一个people MySQL表: CREATE TABLE people ( person_id PRIMARY KEY AUTO_INCREMENT, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, # } I realize these column defs are not valid but this is just […]

无法在RejectionHandler中获取CallableThread

我有线程池,它将带有RejectionHandler Callable工作线程。 我需要在RejectionHandler获取此Callable任务但无法获取它。 在下面的例子中,我需要执行RejectionHandler的可调用任务的uniqueId。 在RejecitonHandler , Runnable是一个FutureTask ,我希望它应该被转换为Callable worker thread。 请帮我在RejectionHandler中获取Callable Worker线程实例。 import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.FutureTask; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class RejectionDemo { RejectionDemo(){ Random random = new Random(); ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new ArrayBlockingQueue(2), new RejectionHandlerImpl()); CallableWorkerThread workers[] = new CallableWorkerThread[10]; for (int […]

什么是等待的最佳替代方案…通知低级同步?

据我所知, wait()和notify()已被更好的并发机制所取代。 那么,您可以选择哪种更好的替代方案,比如实现同步队列 ? 他们究竟是什么“更好”? 编辑 :这(“实现同步队列”)是一个面试问题。 可接受的答案不能使用BlockingQueue或其他队列实现。 但是,它可能使用其他同步构造,例如CountDownLatch。 我没有详尽的允许和禁止课程列表 – 使用你的头脑。

notifyAll()抛出IllegalMonitorStateException

我正在设计两个线程:一个必须得到播放器的名称,第二个线程必须等待设置的名称才能继续,但第一个线程中的notify()all抛出了IllegalMonitorStateException错误。 private NameFecth nameFetch; private UseName useName; private Object nameSetLock; public static void method{ nameSetLock = new Object() nameFetch = new NameFetch(nameSetLock); useName = new UseName(nameSetLock); Thread nameFetchThread = new Thread(nameFetch); nameFetchThread.start(); Thread useNameThread = new Thread(useName); useNameThread.start(); } public class NameFetch implements Runnable{ /*variables and constructers*/ public void run(){ /*get name and set the […]

长变量的primefaces增量?

如果长变量声明为: – private volatile long counter = 0; 现在,如果我使用预增量运算符递增它,那么操作是primefaces的吗? 如果是,那么它会比java.util.concurrent.atomic.AtomicLong对象的增量更有效吗?

Java中的并发字节数组访问,尽可能少的锁

我正在尝试减少分段数据的锁定对象的内存使用量。 在这里和这里看我的问题。 或者假设你有一个字节数组,每16个字节可以(de)序列化为一个对象。 我们将其称为行,行长度为16个字节。 现在,如果您从编写器线程修改这样的行并从多个线程读取,则需要锁定。 如果你的字节数组大小为1MB(1024 * 1024),这意味着65536行和相同数量的锁。 这有点太多了,我还需要更大的字节数组,我想把它减少到大致与线程数成比例的东西。 我的想法是创造一个 ConcurrentHashMap concurrentMap; 其中Integer是行索引,在线程“输入”行之前,它会在此映射中放置一个锁定对象(从这个答案中得到了这个想法)。 但无论我怎么想,我都找不到真正的线程安全的方法: // somewhere else where we need to write or read the row LockHelper lock1 = new LockHelper(); LockHelper lock = concurrentMap.putIfAbsent(rowIndex, lock1); lock.addWaitingThread(); // is too late synchronized(lock) { try { // read or write row at rowIndex eg writing like […]

如何按顺序在ExecutorService中执行任务?

我有三个连接的线程,即第二个线程在第一个死后执行。 这是我的代码: public class Main { public static void main(String args[]) throws Exception { final Thread thrdA = new Thread(() -> System.out.println(“Message 1”)); final Thread thrdB = new Thread(() -> System.out.println(“Message 2”)); final Thread thrdC = new Thread(() -> System.out.println(“Message 3”)); thrdA.start(); thrdA.join(); thrdB.start(); thrdB.join(); thrdC.start(); thrdC.join(); } } 如何使用ExecutorService而不是三个线程对象实现此function?

在计算时在JTextArea中显示文本

我正在编写的应用程序包括JButton和JTextArea。 单击该按钮会导致计算时间过长,从而导致JTextArea中显示文本。 即使计算时间很长,我也可以随时随地获得中间结果(例如,想想一个近似于pi的100位数的应用程序 – 每隔几秒我就可以编写另一个数字)。 问题是,即使我写(在ActionListener类中,因为按钮调用了计算)来将JTextArea的文本设置为某些东西,它在计算完成时也不显示,我只能看到结束结果,计算结束后。 为什么会这样,我该如何解决? 先谢谢你。

在java中同步对象,然后更改synchronized-on变量的值

我遇到了这样的代码 synchronized(obj) { obj = new Object(); } 有些事情对此感觉不对,我无法解释,这段代码是好的还是有什么问题,请指出来。 谢谢