我偶尔很难在我的一个线程挂起的地方复制bug。
由于文件处理器移动文件(根据逻辑需要)只能在文件已经在目录中时发生,所以文件处理器文件读取过程是异步的,不可能导致挂起。
但是,文件处理器线程也会扫描目录,这可能发生在web蜘蛛线程将文件保存到目录中时。
问题:如果一个文件被保存到这个目录中,而下面的读取目录方法被调用,它会导致挂起吗?(坦白地说,我不知道它是怎么回事,但也许这就是我有这个错误的原因。)
如果是,那我该如何解决这个问题?
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");
}发布于 2016-07-12 21:36:49
为了避免线程相互干扰,应该使用信号量(或它最简单的形式中的互斥)。Sempaphores可以由线程获取,以便在所谓的关键部分运行代码。例如,本节中的代码可以访问ArrayList。如果多个线程访问该列表并向其添加和删除元素,您最终将得到一个ConcurrentModificationException。在其他情况下,您将完全不会得到异常,但是您的程序可能会做一些意想不到的事情(例如,请参阅丢失更新问题 )。
但是,如果每次访问关键部分时都会获得一个锁,那么其他线程将无法访问共享资源(本例中的列表或在本例中的目录)。
为了实现这种行为,您可以使用实现锁接口的类,创建对象并将其作为锁使用,如下所示:
Object lock = new Object();
synchronized(lock) {
// do critical work here
}第三种也可能是最无效(但最简单)的方法是为您的方法使用synchronized关键字。一次只能调用一个在类中声明为同步的方法。
https://stackoverflow.com/questions/38338718
复制相似问题