首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java: ExecutorService错误

Java: ExecutorService错误
EN

Stack Overflow用户
提问于 2015-12-13 14:13:20
回答 1查看 1.5K关注 0票数 0

我对ExecutorService有点陌生,我对它有一个问题。我有一节课:

代码语言:javascript
复制
      @Override
      public void updateAvatar(final MultipartFile multipartFile, final String speakerId) {

        final GridFS avatarGfs = new GridFS(getTemplate().getDb(), SPEAKER_AVATAR_COLLECTION);

        // Remove all sizes
        avatarGfs.remove(new BasicDBObject(SPEAKER_ID_FIELD, speakerId));
        System.out.println("hello from updateAvatar");

        ExecutorService executorService = Executors.newFixedThreadPool(3);
        executorService.execute(new Runnable() {
          public void run() {
            for (SpeakerAvatarSize size : SpeakerAvatarSize.values()) {
              try {

                System.out.println("calling saveAvatar");
                saveAvatar(multipartFile, speakerId, size, avatarGfs);

              } catch (IOException e) {

                LOG.error("SpeakerRepository#updateAvatar", e);
              }
            }
          }
        });

        executorService.shutdown();
        System.out.println("shut down threads");
      }

在编辑当前的用户化身时,以及添加另一个化身时,我都会得到这个错误。似乎只增加了一个化身:

代码语言:javascript
复制
Exception in thread "pool-2-thread-1" java.lang.IllegalStateException: File has been moved - cannot be read again
    at org.springframework.web.multipart.commons.CommonsMultipartFile.getInputStream(CommonsMultipartFile.java:123)
    at util.ImageScaleUtil.scale(ImageScaleUtil.java:26)
    at impl.SpeakerRepository.saveAvatar(SpeakerRepository.java:97)
    at impl.SpeakerRepository.access$000(SpeakerRepository.java:28)
    at impl.SpeakerRepository$1.run(SpeakerRepository.java:81)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

提前谢谢你!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-13 14:34:18

您使用executor服务,因此saveAvatar函数可能会在updateAvater完成后运行。那时,web框架可能已经清理了multipartFile。

要等待执行程序服务,只需添加:

代码语言:javascript
复制
executorService.shutdown();
System.out.println("shut down threads");
try {
    executorService.awaitTermination(60, TimeUnit.SECONDS);
} catch (InterruptedException ignored) {
}

顺便说一句,您可以在每个查询中创建一个包含3个线程的executor服务,并且只使用其中的一个线程。由于您必须等待任务完成,所以在那里使用executor服务是没有意义的。

代码语言:javascript
复制
@Override
public void updateAvatar(final MultipartFile multipartFile, final String speakerId) {

  final GridFS avatarGfs = new GridFS(getTemplate().getDb(), SPEAKER_AVATAR_COLLECTION);

  // Remove all sizes
  avatarGfs.remove(new BasicDBObject(SPEAKER_ID_FIELD, speakerId));
  System.out.println("hello from updateAvatar");

  for (SpeakerAvatarSize size : SpeakerAvatarSize.values()) {
    try {
      System.out.println("calling saveAvatar");
      saveAvatar(multipartFile, speakerId, size, avatarGfs);
    } catch (IOException e) {

      LOG.error("SpeakerRepository#updateAvatar", e);
    }
  }
}

或者,如果希望for循环并行运行,则可以使用this answer

代码语言:javascript
复制
@Override
public void updateAvatar(final MultipartFile multipartFile, final String speakerId) {

  final GridFS avatarGfs = new GridFS(getTemplate().getDb(), SPEAKER_AVATAR_COLLECTION);

  // Remove all sizes
  avatarGfs.remove(new BasicDBObject(SPEAKER_ID_FIELD, speakerId));
  System.out.println("hello from updateAvatar");

  Parallel.For(SpeakerAvatarSize.values(), size -> {
    try {
      System.out.println("calling saveAvatar");
      saveAvatar(multipartFile, speakerId, size, avatarGfs);
    } catch (IOException e) {
      LOG.error("SpeakerRepository#updateAvatar", e);
    }
  });
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34252033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档