小编Ami*_*mit的帖子

使用锁和ConcurrentHashMap缺少更新

我有一个场景,我必须维护一个可以由多个线程填充的Map,每个线程修改它们各自的List(唯一标识符/键是线程名称),当线程的列表大小超过固定批量大小时,我们必须保持DB中的记录.

示例代码如下:聚合器类

private volatile ConcurrentHashMap<String, List<T>>  instrumentMap = new ConcurrentHashMap<String, List<T>>();
private ReentrantLock lock ;

public void addAll(List<T> entityList, String threadName) {
    try {
        lock.lock();
        List<T> instrumentList = instrumentMap.get(threadName);
        if(instrumentList == null) {
            instrumentList = new ArrayList<T>(batchSize);
            instrumentMap.put(threadName, instrumentList);
        }

        if(instrumentList.size() >= batchSize -1){
            instrumentList.addAll(entityList);
            recordSaver.persist(instrumentList); 
            instrumentList.clear();
        } else {
            instrumentList.addAll(entityList);  
        }
    } finally {
        lock.unlock();
    }

}
Run Code Online (Sandbox Code Playgroud)

每隔2分钟再运行一个单独的线程(使用相同的锁定)以持久保存Map中的所有记录(以确保每2分钟后持续存在一些内容并且地图大小不会太大)

if(//Some condition) {
    Thread.sleep(//2 minutes);
    aggregator.getLock().lock();
    List<T> instrumentList = instrumentMap.values().stream().flatMap(x->x.stream()).collect(Collectors.toList());
    if(instrumentList.size() > 0) {
        saver.persist(instrumentList);
        instrumentMap .values().parallelStream().forEach(x -> x.clear());
        aggregator.getLock().unlock();
    } …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading

8
推荐指数
1
解决办法
162
查看次数

如何在JPA存储库方法中使用组合键的一部分?

我有一个带有嵌入式 ID 的课程

@Entity
@Table(name="account_table")
Public class AccountLink {

@EmbeddedId
private AccountLinkKey accountLinkKey;
//Rest of code
}

@Embeddable
Public class AccountLinkKey {
//Rest code here

@ColumnName(name="i am hiding")
private String segAccount;

@ColumnName(name="i am hiding")
private String secAccount;
//Rest of code
}
Run Code Online (Sandbox Code Playgroud)

现在在我的存储库中我想要一个仅通过 进行搜索的方法secAccount,那么我应该如何编写findBy..

List<AccountLink> findBy...(String secAccount); 
Run Code Online (Sandbox Code Playgroud)

我尝试过findByAccountLinkKeySecAccount(String secAccount)但仍然没有成功。

java spring jpql spring-data-jpa

3
推荐指数
1
解决办法
2万
查看次数

以下代码线程安全

我有一个场景,我必须维护一个可以由多个线程填充的Map,每个线程都修改相应的List(唯一标识符/键是线程名称),当线程的列表大小超过固定批量大小时,我们必须保持DB中的记录.

示例代码如下:

private volatile ConcurrentHashMap<String, List<T>>  instrumentMap = new ConcurrentHashMap<String, List<T>>();
private ReadWriteLock lock ;

public void addAll(List<T> entityList, String threadName) {
    try {
        lock.readLock().lock();
        List<T> instrumentList = instrumentMap.get(threadName);
        if(instrumentList == null) {
            instrumentList = new ArrayList<T>(batchSize);
            instrumentMap.put(threadName, instrumentList);
        }

        if(instrumentList.size() >= batchSize -1){
            instrumentList.addAll(entityList);
            recordSaver.persist(instrumentList); 
            instrumentList.clear();
        } else {
            instrumentList.addAll(entityList);  
        }
    } finally {
        lock.readLock().unlock();
    }

}
Run Code Online (Sandbox Code Playgroud)

每隔2分钟就会再运行一个单独的线程来保存Map中的所有记录(以确保每隔2分钟后我们会持续存在一些内容并且地图大小不会太大)并且当它启动时它会阻止所有其他线程(检查readLock和writeLock usawhere writeLock具有更高的优先级)

if(//Some condition) {
                    Thread.sleep(//2 minutes);
                    aggregator.getLock().writeLock().lock();
                    List<T> instrumentList = instrumentMap .values().stream().flatMap(x->x.stream()).collect(Collectors.toList());
                    if(instrumentList.size() > 0) {

                        saver.persist(instrumentList);
                        instrumentMap .values().parallelStream().forEach(x -> …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading hashmap concurrenthashmap

3
推荐指数
1
解决办法
97
查看次数