我有一些代码需要以一种非常聪明的方式锁定。假设我需要锁定一个代码部分,该部分执行一些http请求,基本上更新一些文本文件。
此操作可以按其名称处理给定的文件。
我的伪码:
public void UpdateFile(int id){
dal.invokeHTTPutRequest(id, fileContent);
}我希望这段代码在某种程度上成为synchronized/lock
有什么想法吗?
发布于 2017-12-26 07:48:15
在由数据库或缓存(如redis)或其他仲裁中间件(如zookeeper和ETCD)实现的分布式锁中,这是很常见的。
这里提供了一个简单的实现,而没有基于Guava的其他中间件:
导入com.google.Common.cache。*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockUtil {
private static final LoadingCache<Integer, Lock> lockCache = CacheBuilder.newBuilder().maximumSize(Long.MAX_VALUE).build(new CacheLoader<Integer, Lock>()
{
@Override
public Lock load(Integer i)
{
return new ReentrantLock();
}
});
public static Lock getLock(int id) throws ExecutionException {
return lockCache.get(id);
}
}你可以用ConcurrentHashMap代替;
对于超时,可以使用tryLock(超时)而不是lock()
发布于 2017-12-26 07:46:00
对于您来说,一个简单的解决方案是使用的HashMap,在hashmap中,您可以使用文件if作为检索松弛的reentrantlock的密钥。
发布于 2017-12-26 08:02:32
我尝试了字符串池来获得同步监视器对象。对我来说似乎没问题,请评论一下这个实现。
import java.util.*;
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
List<Callable<String>> taskList = new ArrayList<>();
taskList.add(() -> abcd(1));
taskList.add(() -> abcd(3));
taskList.add(() -> abcd(1));
taskList.add(() -> abcd(1));
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.invokeAll(taskList);
}
private static String abcd(int id) throws InterruptedException {
synchronized (String.valueOf(id).intern()){
System.out.println(id +" - "+Thread.currentThread().getId());
Thread.sleep(2000l);
}
return String.valueOf(id);
}
} 希望你能像这样使用
public void UpdateFile(int id) {
synchronized (String.valueOf(id).intern()) {
dal.invokeHTTPutRequest(id, fileContent);
}
}https://stackoverflow.com/questions/47975219
复制相似问题