Java 使用ExecutorService和BlockingQueue可运行锁定(驻车)

Java 使用ExecutorService和BlockingQueue可运行锁定(驻车),java,executorservice,blockingqueue,linkedblockingqueue,Java,Executorservice,Blockingqueue,Linkedblockingqueue,注意:我了解网站的规则,但我无法将所有代码(复杂/大型代码)放入网站 我放了一个不同的(所有真正的代码都太多了,你在这里不需要)代码,但复制了问题(主类是joseluisbz.mock.support.testoptimizedsp,切换类是joseluisbz.mock.support.runnable.ProcessorDSP)就像视频一样 请不要向我推荐用于此代码的其他jar或外部库 我希望我能说得更具体些,但我不知道该提取和展示什么部分。 在你结束这个问题之前:显然,如果有人告诉我去哪里

注意:我了解网站的规则,但我无法将所有代码(复杂/大型代码)放入网站

我放了一个不同的(所有真正的代码都太多了,你在这里不需要)代码,但复制了问题(主类是
joseluisbz.mock.support.testoptimizedsp
,切换类是
joseluisbz.mock.support.runnable.ProcessorDSP
)就像视频一样

请不要向我推荐用于此代码的其他jar或外部库

我希望我能说得更具体些,但我不知道该提取和展示什么部分。 在你结束这个问题之前:显然,如果有人告诉我去哪里看(技术细节),我愿意改进我的问题

我做了一个演讲以表明我的观点

甚至为了阐述这个问题,我还画了一张图表来说明情况

我的程序有一个
JTree
,显示
工作者之间的关系


我使用
ExecutorService ExecutorService=Executors.newCachedThreadPool()在控制生命周期的线程之间建立了一个图表交互
列表首先,设置线程名称的方式是错误的。您可以使用以下模式:

public class Test
{
    public static class Task implements Runnable
    {
        public Task()
        {
            Thread.currentThread().setName("Task");
        }

        @Override
        public void run()
        {
            System.out.println("Task: "+Thread.currentThread().getName());
        }
    }

    public static void main(String[] args)
    {
        new Thread(new Task()).start();
        System.out.println("Main: "+Thread.currentThread().getName());
    }
}
这会产生(不期望的)结果:

这是不正确的,因为在
任务
构造函数中,线程尚未启动,因此您正在更改调用线程的名称,而不是生成线程的名称。您应该在
run()
方法中设置名称

因此,屏幕截图中的线程名称是错误的

现在才是真正的问题。在中,您有以下行:

List<ChunkDTO> listDelayedChunkDTO = mapListDelayedChunkDTO.putIfAbsent(chunkDTO.getPitch(), new ArrayList<>());
这意味着您将
null
作为
listdayedchunkdto
参数传递。因此,当这一行在
ProcessorDSP
中执行时:

if (listDelayedChunkDTO.size() > 2) {

它抛出一个
NullPointerException
,runnable停止。

我不太清楚你问题的背景。你能创建一个吗?@JacobG。现在,我上传了一个视频来显示这个问题,因为我不知道原因,我不知道为了重复ant在这里提出的问题提取了什么代码。(我需要等待1个小时)我可以理解,如果您使用的是
集合#synchronizedMap
,它为什么会阻塞,但如果您只是使用
HashMap
,则不会阻塞。使用
新建HashMap(),结果是相同的
集合.synchronizedMap(新的HashMap())
每个Runnable都是这样启动的:listFuture().add(executorService().submit(this));在其构造函数中。
听起来像是“泄漏”引用,请尽量避免这种情况。jfyi:我发现您在中对
putIfAbsent()
的使用也不正确。请注意,即使条目已经存在,也始终会计算第二个参数!这意味着您将始终创建一个
WorkerDSPPitchIncrement()
对象,这显然是不可取的。我理解,根据实现,它不应返回null<代码>V=map.get(键);如果(v==null){v=map.put(key,value);}返回v我改为
V=map.get(键);如果(v==null){map.put(key,value);v=map.get(key);}返回v
@joseluisbz返回“如果键没有映射,则返回null”,因此这是预期的行为。您认为使用
List listdayedchunkdto=new ArrayList()更好吗
列表listDelayedChunkDTO=Collections.synchronizedList(新的ArrayList())在WorkerDSPDecrement、WorkerDSPFilter、WorkerDSPPitchIncrement和
Map-mapWorkerDSPPitchIncrement=new HashMap()
映射mapWorkerDSPPitchIncrement=Collections.synchronizedMap(新HashMap())输入WorkerDSP@joseluisbz这取决于集合是否被并发访问。如果只有一个线程访问它们,那么就没有理由使它们同步。
Main: Task
Task: Thread-0
List<ChunkDTO> listDelayedChunkDTO = mapListDelayedChunkDTO.putIfAbsent(chunkDTO.getPitch(), new ArrayList<>());
ProcessorDSP processorDSP = new ProcessorDSP(controlDSP, upNodeDSP, null,
   dHnCoefficients, chunkDTO, listDelayedChunkDTO, Arrays.asList(parent.getParentBlockingQueue()));
if (listDelayedChunkDTO.size() > 2) {