【问题标题】:Java sempahore optionsJava 信号量选项
【发布时间】:2013-06-10 19:04:41
【问题描述】:

我正在编写一个应用程序,其中可能有多个线程尝试修改同一个文件。为了克服这个问题,我考虑将文件名存储在并发哈希图中,文件名计数并使用等待和通知,即

if(map has fileName){
 map.put(fileName, map.get(fileName)++ )
 wait()
}else{
 map.put(fileName,1)
}

modifyFile(fileName);

{
 count = map.get(fileName);
 if count == 1 then map.remove(fileName)
 else map.put(fileName, count-- )
 notify()
}

但我不觉得上面的代码很优雅。有一个更好的方法吗?
编辑:一个简单的锁会阻塞所有线程的流。我只是想阻塞想要修改同一个文件的线程,其他线程应该不受影响

【问题讨论】:

  • 鉴于您编写的是伪代码,因此很难准确地告诉您想要什么。除了简单的锁之外,您还需要什么吗?
  • @JonSkeet 一个简单的锁会阻塞所有线程的流。我只是想阻塞想要修改同一个文件的线程,其他线程应该不受影响
  • 不,简单的锁只会阻塞试图获取锁的线程。
  • @Joel 是的,简单的锁是指所有线程都使用相同的锁对象
  • 您是否担心其他程序或其他JVM修改文件?或者只是你正在运行的一个 JVM?

标签: java multithreading synchronization semaphore


【解决方案1】:

您的代码实际上不是线程安全的。在从映射中移除对象之前,多个线程可以同时通过if count == 1 检查。

java.util.concurrent

包含一个可以更好地工作的信号量实现。然后只需使用哈希图来存储信号量。不要添加/删除信号量,只需访问它们。然后同步工作由信号量完成,而不是你的地图。

modifyFile(fileName);
{
 semaphore = map.get(fileName);
 semaphore.acquire(1);
 doWork();
 semaphore.release(1);
}

【讨论】:

  • 是的,不好意思,匆忙写了伪代码。上述解决方案的唯一问题是地图开始累积对象,并且有> 2k资源/文件
  • @Rnet:你认为 2000 个对象真的可能是个问题吗?虽然在您进行过程中进行清理会很好,但除非这是一项长期运行的服务,否则我可能不会打扰。
  • @JonSkeet 是的,我想你是对的,但是让物体像那样堆积,虽然知道什么都不会发生,但仍然感觉有点……嗯,不满意
  • @Rnet:就我个人而言,我宁愿编写简单的代码,它显然是正确的,但会留下一些包袱,而不是需要花费数小时检查它是否是线程安全的代码 :) 它确实取决于你正在编写的那种应用程序。
  • 让 WeakHashMap 帮你整理一下怎么样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多