Java 线程安全访问计数器
我正在尝试实现线程安全访问计数器。我需要做的是创建一个包含路径和整数计数器的HashMap。它有两种方法,用于检查映射是否包含路径,并在路径出现时相应地增加计数,如下所示Java 线程安全访问计数器,java,multithreading,Java,Multithreading,我正在尝试实现线程安全访问计数器。我需要做的是创建一个包含路径和整数计数器的HashMap。它有两种方法,用于检查映射是否包含路径,并在路径出现时相应地增加计数,如下所示 public class AccessCounter { private HashMap<Integer,java.nio.file.Path> counter= new HashMap<Integer,java.nio.file.Path>(); private ReentrantLock lock
public class AccessCounter {
private HashMap<Integer,java.nio.file.Path> counter= new HashMap<Integer,java.nio.file.Path>();
private ReentrantLock lock = new ReentrantLock();
private Path path ;
private RequestHandler rq;
public void map(HashMap<Integer,java.nio.file.Path> counter){
counter.put(10,Paths.get("/Users/a.html"));
counter.put(5, Paths.get("b.html"));
counter.put(2, Paths.get("c.txt"));
counter.put(7, Paths.get("d.txt"));
}
public void increment(){
lock.lock();
System.out.println("Lock Obtained");
try{
if(counter.keySet().equals(rq.fileName())){
for(Integer key: counter.keySet()){
Path text = counter.get(key);
key++;
}
}
else {
counter.put(1,path);
}
}finally{
lock.unlock();
System.out.println("Lock released");
}
}
public void getCount(){
lock.lock();
System.out.println("Lock Obtained");
try{
if(counter.keySet().equals(rq.fileName())){
for(Integer key: counter.keySet()){
Path text = counter.get(key);
key++;
}
}
else {
return ;
}
}finally{
lock.unlock();
System.out.println("Lock released");
}
}
}
私有HashMap计数器=新建
哈希图
您需要的不是HashMap,而是HashMap,因为您的目的是计算具有相同路径的条目数
我看到了一个很好的优化,除非您想尝试使用普通HashMap并在用户代码中锁定:
您可以使用ConcurrentHashMap代替上面的HashMap
ConcurrentHashMap有一个putIfAbsent。。。方法,该方法在单个语句中以原子方式执行它
AtomicInteger允许我们使用incrementAndGet方法以原子方式递增
在用户代码中都没有额外的锁/同步
私有HashMap计数器=新建
哈希图
您需要的不是HashMap,而是HashMap,因为您的目的是计算具有相同路径的条目数
我看到了一个很好的优化,除非您想尝试使用普通HashMap并在用户代码中锁定:
您可以使用ConcurrentHashMap代替上面的HashMap
ConcurrentHashMap有一个putIfAbsent。。。方法,该方法在单个语句中以原子方式执行它
AtomicInteger允许我们使用incrementAndGet方法以原子方式递增
这两种方法在用户代码中都没有额外的锁/同步。使用ConcurrentHashMap和AtomicLong是线程安全性和简单性所需要的
final ConcurrentMap<Path, AtomicLong> counterMap = new ConcurrentHashMap<>();
public void incrementFor(Path path) {
counterMap.computeIfAbsent(path, p -> new AtomicLong()).incrementAndGet();
}
public long getCount(Path path) {
AtomicLong l = counterMap.get(path);
return l == null ? 0 : l.get();
}
ComputeFabSent将以线程安全的方式根据需要放置一个新的原子
注意:由于ConcurrentMap支持并发访问,您可以让多个线程同时使用此映射,前提是它们使用ConcurrentHashMap和AtomicLong访问不同的路径,这是线程安全性和简单性所需要的
final ConcurrentMap<Path, AtomicLong> counterMap = new ConcurrentHashMap<>();
public void incrementFor(Path path) {
counterMap.computeIfAbsent(path, p -> new AtomicLong()).incrementAndGet();
}
public long getCount(Path path) {
AtomicLong l = counterMap.get(path);
return l == null ? 0 : l.get();
}
ComputeFabSent将以线程安全的方式根据需要放置一个新的原子
注意:由于ConcurrentMap支持并发访问,您可以让多个线程同时使用此映射,前提是它们正在访问不同的路径我想您希望映射为HashMap,而不是HashMap,因为您希望计算具有相同路径的条目数。是吗?是的,这正是我需要做的。我会解决的。感谢您提供的类似信息,以及您不想使用ConcurrentHashMap的原因。这有一个putIfAbsent方法,它以原子方式执行,而AtomicInteger可以使用incrementAndGet方法以原子方式递增,而不需要在用户代码中进行任何锁定/同步。我认为您希望映射为HashMap而不是HashMap,因为您希望拥有具有相同路径的条目的计数。是吗?是的,这正是我需要做的。我会解决的。感谢您提供的类似信息,以及您不想使用ConcurrentHashMap的原因。这有一个putIfAbsent方法,它以原子方式执行,AtomicInteger可以使用incrementAndGet方法以原子方式递增,而用户代码中没有任何锁定/同步。感谢您的建议!肯定会有所改变。目前,您是否看到代码中有任何错误,因为我无法运行it@Azib.H我认为需要做一些改变。RequestHandler中的ac未初始化。您需要确保两个线程使用相同的ac,否则每个ac都有自己的HashMap。我看不出你在哪里叫地图。。。方法交流。即使在选择。。。方法创建三个文件实例,但不在任何地方使用。最后,用最新的代码更新您的问题。谢谢您的建议!肯定会有所改变。目前,您是否看到代码中有任何错误,因为我无法运行it@Azib.H我认为需要做一些改变。RequestHandler中的ac未初始化。您需要确保两个线程使用相同的ac,否则每个ac都有自己的HashMap。我看不出你在哪里叫地图。。。方法交流。即使在选择。。。方法创建三个文件实例,但不在任何地方使用。最后,用最新的代码更新你的问题。这看起来更简单更好+谢谢各位!这看起来更简单更好+谢谢各位!真的很有帮助