首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java :用DirectoryStream进行多线程

Java :用DirectoryStream进行多线程
EN

Stack Overflow用户
提问于 2016-07-12 20:54:58
回答 1查看 492关注 0票数 0

我偶尔很难在我的一个线程挂起的地方复制bug。

  • web蜘蛛线程将html文件转储到目录中。
  • 文件处理线程读取目录中的文件,逐个处理并移动它们。

由于文件处理器移动文件(根据逻辑需要)只能在文件已经在目录中时发生,所以文件处理器文件读取过程是异步的,不可能导致挂起。

但是,文件处理器线程也会扫描目录,这可能发生在web蜘蛛线程将文件保存到目录中时。

问题:如果一个文件被保存到这个目录中,而下面的读取目录方法被调用,它会导致挂起吗?(坦白地说,我不知道它是怎么回事,但也许这就是我有这个错误的原因。)

如果是,那我该如何解决这个问题?

代码语言:javascript
复制
 private void listFiles(Path path)
{
    Log.getLogger().debug("started ......");
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(path))
    {
        for (Path entry : stream)
        {
            if (Files.isDirectory(entry))
            {
                listFiles(entry);
            }
            else
            {
                files.add(entry);
            }
        }
    }
    catch (Exception e)
    {
        Log.getLogger().error(e.getMessage(), e);
    }
    Log.getLogger().debug("done");
}
EN

回答 1

Stack Overflow用户

发布于 2016-07-12 21:36:49

为了避免线程相互干扰,应该使用信号量(或它最简单的形式中的互斥)。Sempaphores可以由线程获取,以便在所谓的关键部分运行代码。例如,本节中的代码可以访问ArrayList。如果多个线程访问该列表并向其添加和删除元素,您最终将得到一个ConcurrentModificationException。在其他情况下,您将完全不会得到异常,但是您的程序可能会做一些意想不到的事情(例如,请参阅丢失更新问题 )。

但是,如果每次访问关键部分时都会获得一个锁,那么其他线程将无法访问共享资源(本例中的列表或在本例中的目录)。

为了实现这种行为,您可以使用实现锁接口的类,创建对象并将其作为锁使用,如下所示:

代码语言:javascript
复制
Object lock = new Object();

synchronized(lock) {
  // do critical work here
}

第三种也可能是最无效(但最简单)的方法是为您的方法使用synchronized关键字。一次只能调用一个在类中声明为同步的方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38338718

复制
相关文章

相似问题

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