当前位置: 首页 > 知识库问答 >
问题:

使用ExecutorService和BlockingQueue可运行锁定(公园)

容俊豪
2023-03-14

注意:我理解规则站点,但我不能把所有代码(复杂/大代码)。

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

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

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

我制作了一个视频来展示我的问题。

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

我的程序有一个JTree,显示了Worker之间的关系。

我用ExecutorService=Executors在控制生命周期的线程之间建立了一个交互图。newCachedThreadPool() 列表

每个Runnable都是这样启动的listFuture()。添加(executorService()。提交(这个) 在其构造函数中。列表是这样创建的:BlockingQueue

我的图表显示了工人的父亲是谁,如果他有父亲的话。它还显示了阻塞队列之间的写入关系。

RunnableStopper停止Workerlike属性中包含的相关runnablesRunnableDecrementerRunnableDecrementerrunnabledfilter以一个周期运行它为其阻塞队列所接收的每个自定义。他们总是为其创建一个RunnableProcessor(它没有循环,但由于其处理时间长,一旦任务完成,它应该由GC收集)。

在内部,RunnableIncrementer有一个MapMap

当一些习俗到来时。。。我需要获取lastReceivedCustom的列表List

当我添加以下行时,我的代码停止工作:

if (listDelayedCustom.size() > SomeValue) {
  //No operation has yet been included in if sentence
}

但评论这些台词并不会阻碍你

//if (listDelayedCustom.size() > SomeValue) {
//  //No operation has yet been included in if sentence
//}

有什么建议可以进一步说明我的问题吗?


共有1个答案

华哲茂
2023-03-14

首先,设置线程名称的方式是错误的。您可以使用以下模式:

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());
    }
}

给出(不希望的)结果:

Main: Task
Task: Thread-0

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

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

现在真正的问题是。在WorkerDSP增量中,您有这样一行:

List<ChunkDTO> listDelayedChunkDTO = mapListDelayedChunkDTO.putIfAbsent(chunkDTO.getPitch(), new ArrayList<>());

putIfAbsent()的文档说明:

如果指定的键尚未与值关联(或映射为null),则将其与给定值关联并返回null,否则返回当前值。

由于映射最初是空的,所以第一次调用putIfAbsent(),它将返回null,并将其分配给listdayedchunkdto

然后创建一个ProcessorDSP对象:

ProcessorDSP processorDSP = new ProcessorDSP(controlDSP, upNodeDSP, null,
   dHnCoefficients, chunkDTO, listDelayedChunkDTO, Arrays.asList(parent.getParentBlockingQueue()));

这意味着将null作为listdayedchunkdto参数传递。因此,当这一行在ProcessorDSP中执行时:

if (listDelayedChunkDTO.size() > 2) {

它抛出一个NullPointerException,runnable停止。

 类似资料:
  • 我希望能够获得我已经提交给执行服务(特别是线程池执行器)的Callable(因此它们不能通过getQueue())。 我试图创建一个子类来覆盖beForeExecute之前的

  • 我使用一个Runnable对象来运行processCommand并执行一些需要一定时间的处理(我们称之为insideprocess)。在insideprocess的末尾,它将向文本文件写入一些内容。其思想是,如果在指定的时间内insideprocess仍未完成,则必须将其杀死,因此我使用ExecutorService来处理它。但是如果insideprocess早于指定时间完成,它将中断Execut

  • 问题内容: 我们的一位客户正在使用某些Novell安全软件,有时会锁定我们的软件创建的某些.class文件。发生这种情况时,这会给他们带来一些麻烦的问题,我正在尝试研究一种变通办法,我们可以将其添加到错误处理中以解决此问题。我想知道java api中是否有任何调用可用于检测文件是否已锁定,如果已锁定,则将其解锁。 问题答案: 在尝试写入文件之前,您可以使用File.canWrite()检查Java

  • 我知道我可以使用 我可以将可运行对象添加到executor中,只要池中有线程空闲,它们就会执行 我想限制要添加到executor服务的对象数,即如果我有100个可运行的对象,线程池大小是10,只有20个必须添加到executor服务,其余的必须被拒绝。

  • java.util.concurrent.BlockingQueue接口是Queue接口的子接口,并且还支持诸如在检索元素之前等待队列变为非空的操作,并在存储元素之前等待队列中的空间可用。 BlockingQueue方法 Sr.No. 方法和描述 1 boolean add(E e) 如果可以在不违反容量限制的情况下立即执行此操作,则将指定的元素插入此队列,成功时返回true,如果当前没有可用空间

  • 在B. Goetz的Java实践中的并发,第13.5节说: 在Java5.0中,读锁的行为更像是一个信号量而不是锁,只维护活动读卡器的数量,而不是它们的身份。Java 6中的行为已更改,以跟踪哪些线程已被授予读锁6。 6这种变化的一个原因是,在java 5.0下,锁实现不能区分第一次请求读锁的线程和重入锁请求,这将使公平读写锁容易死锁。 我的问题是公平有什么问题?为什么不公平的读写锁会被死锁屏蔽?