【问题标题】:Is dead lock happening here?这里发生死锁了吗?
【发布时间】:2022-12-18 11:28:39
【问题描述】:

我有代码,其中有两个线程并行运行,首先生成文件并将它们保存在数据库中,如果它们不存在的话。第二个线程,每 5 秒。检查此数据库中是否出现具有 Status.CREATED 的新文件,如果是,则修改它们并将其状态更新为 UPDATED。应用程序突然停止从两个线程进行日志记录,我想这是由死锁引起的,但我不确定它是否可以在这里持续存在。这是代码:

@Autowired
FileRepository fileRepository;

public void run(ExecutorService executorService) {
    AtomicBoolean wasLastFile = new AtomicBoolean(false);
    CompletableFuture.runAsync(() -> {
        log.info("Producer of files started");
        while (!wasLastFile.get()) {
            List<File> filesList = firstFileReader.readFileForPositions(provider, genericProperties);
            for (File file : filesList) {
                // if file already exists in db don't save it
                if (fileRepository.findByProviderAndProvidedId(provider, file.getProvidedId()) == null)
                    fileRepository.save(file); // with Status.CREATED
            }
            if (filesList.isEmpty())
                wasLastFile.set(true);
        }
    }, executorService);
    
    AtomicBoolean producerOfDetailsHasFinished = new AtomicBoolean(false);
    CompletableFuture.runAsync(() -> {
            log.info("Producer of files details started");
            Iterator<File> iterFiles = null;
            while (!wasLastFile.get()) {
                List<File> files = null;
                if (iterFiles == null || !iterFiles.hasNext()) {
                    files = fileRepository.findAllByProviderAndStateIn(provider, Arrays.asList(State.CREATED, State.UPDATING_FAILED));
                    iterFiles = files.iterator();
                }
                if (iterFiles.hasNext()) {
                    File file = iterFiles.next();
                    // modify file, set State.UPDATED or State.UPDATING_FAILED
                    fileRepository.save(file);
                    iterFiles.remove();
                    if (files != null)
                        log.info(provider + " " + files.size() + " files left for update");
                } else {
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            producerOfDetailsHasFinished.set(true);
            log.info("Producer of files details finished");
        }, executorService);
}

File 在这里仅作为示例对象。我创建了thread dump,它显示有 2 个线程在等待,但我不确定这是否表示死锁,没有针对此数据库实现任何事务,只是默认。

【问题讨论】:

    标签: java postgresql multithreading spring-boot deadlock


    【解决方案1】:

    是的,如果找不到文件,就会出现死锁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-14
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 2021-09-04
      • 2013-11-03
      相关资源
      最近更新 更多