首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ZipOutputStream阻塞Vertx事件循环

ZipOutputStream阻塞Vertx事件循环
EN

Stack Overflow用户
提问于 2021-06-03 00:59:59
回答 1查看 78关注 0票数 0

我正在处理这样一个场景:我正在读取目录中的文件,然后创建一个zip文件。但此操作有时会阻塞Vertx线程,并且我在Vertx跟踪中收到以下异常:

代码语言:javascript
复制
021-06-01 14:46:22.533 io.vertx.core.impl.BlockedThreadChecker [WARNING] Thread Thread[vert.x-eventloop-thread-4,5,main]=Thread[vert.x-eventloop-thread-4,5,main] has been blocked for 65088 ms, time limit is 2000 ms
io.vertx.core.VertxException: Thread blocked
    at java.util.zip.Deflater.deflateBytes(Native Method)
    at java.util.zip.Deflater.deflate(Deflater.java:444)
    at java.util.zip.Deflater.deflate(Deflater.java:366)
    at java.util.zip.DeflaterOutputStream.deflate(DeflaterOutputStream.java:251)
    at java.util.zip.DeflaterOutputStream.write(DeflaterOutputStream.java:211)
    at java.util.zip.ZipOutputStream.write(ZipOutputStream.java:331)

下面是我创建zip文件的方法

代码语言:javascript
复制
 private String zipDirectory(File dir, String zipDirName) {
     _log.info("Entered zip file utility2");
     String zipFilePath;

        try(FileOutputStream fos = new FileOutputStream(zipDirName);
            ZipOutputStream zos = new ZipOutputStream(fos);) {
            populateFilesList(dir);
           
            for(String filePath : _filesListInDir){
                _log.info("FILES: "+filePath);
                File file = new File(filePath);
                
                if(!"zip".equals(Files.getFileExtension(file.getName()))) {
                    ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length()+1, filePath.length()));
                    zos.putNextEntry(ze);
                    FileInputStream fis = new FileInputStream(filePath);
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = fis.read(buffer)) > 0) {
                        zos.write(buffer, 0, len);
                    }
                    zos.flush();
                    zos.closeEntry();
                    fis.close();
            
                }else {
                    _log.info("Ignore zip for writing");
                }
                
            }
            Path zipFilePathDir = Paths.get(zipDirName);
            zipFilePath = zipFilePathDir.getFileName().toString();
            _log.info("Zip file name: "+zipFilePath);
            zos.close();
            fos.close();
        } catch (IOException e) {
            zipFilePath = "FAILURE";
            _log.error("Error creating zip file: "+e.getMessage());
        }
        
        return zipFilePath;
    }

有没有人可以提供一些建议,比如我如何确保不会阻塞Vertx上的主事件循环

EN

回答 1

Stack Overflow用户

发布于 2021-06-03 01:13:41

您可以使用Vertx.executeBlocking在Vert.x管理的工作池中运行该方法:

代码语言:javascript
复制
Future<String> fut = vertx.executeBlocking(promise -> promise.complete(zipDirectory(dir, zipDirName));

如果您的方法需要阻塞超过5秒或10秒,您可能还希望创建自己的专用ThreadPool来执行该方法( Vert.x称为WorkerExecutor ),并改用WorkerExecutor.executeBlocking

代码语言:javascript
复制
// Create a WorkerExecutor with 1 thread, where each method call
// can run for 2 minutes before Vertx logs blocked thread warnings
WorkerExecutor we = vertx.createSharedExecutor("zip", 1, 2, TimeUnit.MINUTES)
Future<String> fut = we.executeBlocking(promise -> promise.complete(zipDirectory(dir, zipDirName));
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67809509

复制
相关文章

相似问题

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