读取解压缩文件后解压缩和删除时线程安全

时间:2014-02-15 11:00:15

标签: java

我正在编写一个用于读取zip文件的java代码,该文件将解压缩,当前文件夹中的压缩文件如果尚未被其他线程解压缩,则读取该解压缩文件。阅读解压缩后的文件将被删除。

例如:如果我在位置/用户/家中有一个zip文件test.zip,那么它将在/ user / home中解压缩。读取解压缩后的文件文件被删除。

对于单个用户它工作正常,但我担心的是多个用户尝试访问相同的zip文件(即test.zip)并尝试同时解压缩它。我不能在不影响性能的情况下处理这种情况。我知道我可以使用同步进行解压缩和删除方法,但这会影响我的应用程序的性能,因为第二个用户必须等到第一个请求完成,即使它试图解压缩其他文件。

任何建议都会非常有帮助。感谢。

我正在使用的包含javac的JDK是jdk1.6.0_35

1 个答案:

答案 0 :(得分:1)

听起来你的问题比你问的样子稍微复杂一点。

如果我错了,请纠正我,但真正似乎要问的是,如果对给定文件的解压缩已在进行中,如何继续解压缩其他文件。

很抱歉,我想回答这个问题,但没有时间充分解释,所以希望这很清楚。

如果您不介意同时为多个用户多次解压缩同一文件,则只需解压缩到临时位置即可完成。

如果您不介意占用大量存储空间,请提前解压所有文件并将其解压缩。您甚至可以通过删除在一段时间内未使用的先前解压缩的数据来限制存储,或者在达到缓存大小阈值后删除旧数据。

但是如果你不想让文件解压缩并且你不想一次多次解压缩同一个文件:首先从基础开始,例如:

class ZippedFile {
   public void beginAccess ();
   public void finishAccess ();
}

每个用户在想要访问zip文件时调用beginAccess,并在完成后finishAccess调用class ZippedFile { public static final int BEGIN_ERROR = 0; public static final int BEGIN_BUSY = 1; public static final int BEGIN_OK = 2; private int refcount = 0; public void wantAccess (); // synchronized internally public int beginAccess (); // synchronized internally public void finishAccess (); // synchronized internally } 。接下来,您必须稍微改进一下以允许同步:

// in User somewhere...
void processFiles (List<ZippedFile> files) {

    LinkedList<ZippedFile> remaining = new LinkedList<ZippedFile>(files);

    // increase reference counts ahead of time so we hold the files
    // during this entire operation even if other users finish with
    // them in the mean time.
    for (ZippedFile file:remaining)
        file.wantAccess();

    while (!remaining.isEmpty()) {
        ZippedFile file = remaining.removeFirst();
        int status = file.beginAccess();
        if (status == ZippedFile.BEGIN_ERROR)
           file.finishAccess(); // decrease ref count 
        else if (status == ZippedFile.BEGIN_BUSY)
           remaining.addLast(file); // move to end of queue 
        else if (status == ZippedFile.BEGIN_OK) {
           processFileData(file); // do the work
           file.finishAccess(); // done with file
        }
    }

}

现在有了这个,beginAccess应该解压缩文件并正常返回BEGIN_OK。但是,如果对beginAccess的另一个调用当前正在为另一个用户解压缩该文件,则应该立即返回BEGIN_BUSY。

wantAccess函数应该增加引用计数而不执行任何操作。

finishAccess应该减少引用计数并删除解压缩的内容(如果它达到零)。如果在另一个用户调用beginAccess时,finishAccess正在删除该文件,则对beginAccess的调用也应该返回BEGIN_BUSY。

所以现在你有一个系统可以让你解压缩一个文件但同时如果正在解压缩当前文件则继续下一个文件。 wantAccess的使用将在下面变得更加清晰。请注意,每个wantAccess必须与一个finishAccess完全匹配。

现在,您必须让每个用户处理多个文件,跳过繁忙的文件并稍后返回。你可以这样做:

{{1}}

确保您通过适当的同步实现了wantAccess,beginAccess和finishAccess的实现。您可以存储一个内部标志,指示文件是否已完全解压缩,或者是否正在进行解压缩,并使用它来防止同时发生多次解压缩/删除 - 您无需同步解压缩/删除自己。

这可能是其他更优雅的方式,但希望这是有帮助的。