Tag: concurrency

ExecutorService的shutdown()不会等到所有线程都完成

我有一个代码,其中4个线程同时运行。 我想等到所有这4个线程都完成。 只有在那之后继续app流程。 我尝试了两种方法: Thread#join() ,这种方法按预期工作。 join()之后的代码仅在所有线程完成后执行。 ExecutorService#shutdown() ,这种技术允许在shutdown()之后执行代码,即使并非所有线程都已完成。 代码示例: ExecutorService service = Executors.newFixedThreadPool(cpuCoresNum); for (int i = 0; i { try { foo(); // some long execution function } catch (Exception e) { e.printStackTrace(); } }); } service.shutdown(); System.out.println(“We’re done! All threads are finished!”); 我的问题: 为什么submit()和shutdown()不要等到所有线程都完成并打印«我们已经完成了! 所有线程都已完成!»在调用service.shutdown();之后立即完成! ?

为什么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中同时播放多个字节数组

如何同时播放多个(音频)字节数组? 这个“字节数组”由TargetDataLine记录,使用服务器传输。 到目前为止我尝试过的 使用SourceDataLine: 无法使用SourceDataLine播放多个流,因为write方法会阻塞,直到写入缓冲区。 使用Threads无法修复此问题,因为只有一个SourceDataLine可以同时写入。 使用AudioPlayer类: ByteInputStream stream2 = new ByteInputStream(data, 0, data.length); AudioInputStream stream = new AudioInputStream(stream2, VoiceChat.format, data.length); AudioPlayer.player.start(stream); 这只会对客户产生噪音。 编辑我没有同时收到语音包,它不是同时,更“重叠”。

EJB 3.1容器管理并发与同步

我已经开始阅读有关单例会话bean和用于使用容器管理并发的注释。 与简单地使用’synchronized’关键字相比,我没有看到这样的好处,所以我怀疑有一些重要的东西我不知道。 从Rubinger&Burke,O’Reilly的书“ Enterprise JavaBeans 3.1 ”中考虑这个例子: @javax.ejb.Lock(javax.ejb.LockType.READ) public String concurrentReadOnlyMethod(){…} @javax.ejb.Lock(javax.ejb.LockType.WRITE) public void allowOnlyOneWriteAtATimeMethod(String stringToSet){…} 这比在read-case和在write-case中使用synchronized关键字更好地省略注释更好,如下所示: public String concurrentReadOnlyMethod(){…} public synchronized void allowOnlyOneWriteAtATimeMethod(String stringToSet){…}

执行程序:如果递归创建任务,如何同步等待所有任务完成?

我的问题与此问题密切相关。 正如在那里发布的那样,我希望主线程等到工作队列为空并且所有任务都已完成。 然而,在我的情况下,问题是每个任务可以递归地导致提交新任务以进行处理。 这使收集所有这些任务的未来变得有点尴尬。 我们当前的解决方案使用忙等待循环来等待终止: do { //Wait until we are done the processing try { Thread.sleep(200); } catch (InterruptedException e) { throw new RuntimeException(e); } } while (!executor.getQueue().isEmpty() || numTasks.longValue() > executor.getCompletedTaskCount()); numTasks是一个在创建每个新任务时增加的值。 这有效但我认为由于忙碌的等待而不是很好。 我想知道是否有一种好方法可以使主线程同步等待,直到被明确唤醒。

如何中断ExecutorService的线程

使用Executors.newSingleThreadExecutor()返回的Executors.newSingleThreadExecutor() ,如何中断它?

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

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

JVM如何确保新对象的内存分配的线程安全性

让我们假设这将在一个真正的并行环境中同时发生,一个VM: // Thread 1: new Cat() // Thread 2: new Dog() // Thread 3: new Mouse() JVM如何确保堆上内存分配的线程安全性? 堆是所有线程的一个,它有自己的内部数据。 为简单起见假设一个简单的压缩垃圾收集器实现,-XX:+ UseSerialGC -XX:+ UseParallelGC,带有简单的增量指针,用于标记可用空间的开始和Eden(堆)中的一个连续可用空间。 当为Cat , Dog和Mouse实例分配堆空间时,线程之间必须存在某种同步,否则它们很容易最终被覆盖。 这是否意味着每个新运算符都隐藏在一些同步块中? 这样,许多“无锁”算法实际上并不完全无锁;) 我假设内存分配是由应用程序线程本身同步进行的,而不是由另一个专用线程进行的。 我知道TLAB或线程本地分配缓冲区。 它们允许线程在Eden中具有单独的存储区域以进行分配,因此不需要同步。 但我不确定TLAB是否默认设置,这是一个非常模糊的HotSpotfunction。 注意:不要混淆TLAB和ThreadLocal变量! 我还假设,对于更复杂的垃圾收集器,如G1或非压缩垃圾收集器,必须维护更复杂的堆结构数据,如CMS的空闲块列表,因此需要更多同步。 更新 :请让我澄清一下。 我接受HotSpot JVM实现的答案以及有和没有活动TLAB的变体。 更新 :根据我的快速测试 , TLAB在我的64位JDK 7上默认设置为串行,并行和CMS垃圾收集器,但不适用于G1 GC。

锁定任意键的处理程序

我有代码实现任意键的“锁定处理程序”。 给定一个key ,它确保一次只有一个线程可以process该(或等于)密钥(这意味着调用externalSystem.process(key)调用)。 到目前为止,我有这样的代码: public class MyHandler { private final SomeWorkExecutor someWorkExecutor; private final ConcurrentHashMap lockMap = new ConcurrentHashMap(); public void handle(Key key) { // This can lead to OOM as it creates locks without removing them Lock keyLock = lockMap.computeIfAbsent( key, (k) -> new ReentrantLock() ); keyLock.lock(); try { someWorkExecutor.process(key); } finally { keyLock.unlock(); […]