首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java智能锁机制

Java智能锁机制
EN

Stack Overflow用户
提问于 2017-12-26 07:20:10
回答 3查看 218关注 0票数 1

我有一些代码需要以一种非常聪明的方式锁定。假设我需要锁定一个代码部分,该部分执行一些http请求,基本上更新一些文本文件。

此操作可以按其名称处理给定的文件。

我的伪码:

代码语言:javascript
复制
public void UpdateFile(int id){
     dal.invokeHTTPutRequest(id, fileContent);
}

我希望这段代码在某种程度上成为synchronized/lock

  1. 锁定将只发生在给定的id。因此,如果请求id 1,然后请求对id 1的另一个请求,它将等待。但是,如果对id 2的请求将到达,它将不会等待。
  2. 我希望有一些超时,所以如果有很多请求到达,所以需要很多时间,他们将得到一个异常。

有什么想法吗?

EN

回答 3

Stack Overflow用户

发布于 2017-12-26 07:48:15

在由数据库或缓存(如redis)或其他仲裁中间件(如zookeeper和ETCD)实现的分布式锁中,这是很常见的。

这里提供了一个简单的实现,而没有基于Guava的其他中间件:

导入com.google.Common.cache。*;

代码语言:javascript
复制
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()

票数 1
EN

Stack Overflow用户

发布于 2017-12-26 07:46:00

对于您来说,一个简单的解决方案是使用的HashMap,在hashmap中,您可以使用文件if作为检索松弛的reentrantlock的密钥。

票数 0
EN

Stack Overflow用户

发布于 2017-12-26 08:02:32

我尝试了字符串池来获得同步监视器对象。对我来说似乎没问题,请评论一下这个实现。

代码语言:javascript
复制
  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);
        }

  } 

希望你能像这样使用

代码语言:javascript
复制
    public void UpdateFile(int id) {
      synchronized (String.valueOf(id).intern()) {
        dal.invokeHTTPutRequest(id, fileContent);
      }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47975219

复制
相关文章

相似问题

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