本文介绍了Java并发:ReadWriteLock变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法将同步的功能与 java.util.concurrent.locks.ReentrantReadWriteLock 。更具体地说,我想要一个方法锁定只有当 WriteLock 被设置,但我想锁定在一个对象变量,如 synchronized 。下面的示例有助于说明:

    public void methodOne(String var){
lock.writeLock()。lock;
try {
//处理
}
finally {
lock.writeLock()。unlock();
}
}

public void methodTwo(String var){
lock.readLock()。lock;
try {
//处理
}
finally {
lock.readLock()。unlock();
}
}

在此示例中,只要 writeLock 上的没有被锁定,这是好的和我正在寻找的功能,但是当 writeLock 被锁定,它被锁定所有情况下 var 。相反,我希望它只锁定 var 同步



同步示例

  public void methodOne(String var){
synchronized(var){
//处理
}
}

public void methodTwo(String var){
synchronized(var){
//正在处理
}
}

只有阻塞条件的输入。这是好的,我正在寻找,但是如果有多个并发调用 methodTwo 用相同的键,他们会阻塞。相反,我想这是一个读样式的锁,并允许调用。



基本上,我想要一个ReadWriteLock,我可以同步到一个变量获得两个功能集。

解决方案

首先,根据不同的数字,这可能会创建一些大量的锁。你可能会考虑使用某种分类或某种东西,所以你可以将更新分成一个小数字。例如,是否有一种方式可以细分不同的var值。也许有各种类型的值?如果有一个小的固定数量的值,那么这不会是一个问题。



你将不得不建立一些 ReentrantReadWriteLock 。也许可以使用 ConcurrentHashMap 来存储所有的锁。

  ; String,ReadWriteLock>。 lockMap = 
new ConcurrentHashMap< String,ReadWriteLock>():
...
public void writeProcessing(String var){
lock = lockMap.get(var);
lock.writeLock()。lock;
try {
//处理
} finally {
lock.writeLock()。unlock();
}
}

您需要事先注册不同的值。或者你可以按需创建。再次,这可能会创建一些大量的锁,这可能是禁止的。

  public void writeProcessing(String var){
lock = getLockForVar(var);
...
}

private ReadWriteLock getLockForVar(String var){
ReadWriteLock lock = lockMap.get(var);
if(lock!= null){
return lock;
}
//这可能会因为竞争条件而创建一个额外的锁
lock = new ReadWriteLock();
ReadWriteLock current = lockMap.putIfAbsent(var,lock);
if(current == null){
return lock;
} else {
return current;
}
}


I am looking for a way to combine functionality from synchronized with functionality from java.util.concurrent.locks.ReentrantReadWriteLock. More specifically, I would like one method to lock only if the WriteLock is set, but I want the lock to be on an object variable like synchronized. Here are examples that will help explain:

ReentrantReadWriteLock Example

public void methodOne(String var) {
    lock.writeLock().lock;
    try {
        // Processing
    }
    finally {
        lock.writeLock().unlock();
    }
}

public void methodTwo(String var) {
    lock.readLock().lock;
    try {
        // Processing
    }
    finally {
        lock.readLock().unlock();
    }
}

In this example, methodTwo can be invoked without blocking as long as the writeLock on methodOne has not been locked. This is good and the functionality I'm looking for, however when the writeLock is locked, it is locked for all cases of var. Instead, I would like for it only to lock on var like with synchronized:

Synchronized Example

public void methodOne(String var) {
    synchronized(var) {
        // Processing
    }
}

public void methodTwo(String var) {
    synchronized(var) {
        // Processing
    }
}

Now, the methods will only block conditional on the input. This is good and and what I'm looking for, however if there are multiple concurrent calls to methodTwo with the same key, they will block. Instead, I would like this to be a "read" style lock and allow the call.

Essentially, I would like a ReadWriteLock that I can synchronize to a variable to obtain both sets of functionality.

解决方案

First off, depending on the number different values, this might create some huge number of locks. You might consider having some sort of classification or something so you can partition the updates to a small number instead. For example, is there a way you can subdivide the different var values. Maybe there are various types of values? If there is a small fixed number of values then this won't be a problem.

You are going to have to build some sort of collection of ReentrantReadWriteLock. Maybe use a ConcurrentHashMap which will store all of the locks.

Map<String, ReadWriteLock> lockMap =
    new ConcurrentHashMap<String, ReadWriteLock>():
...
public void writeProcessing(String var) {
    lock = lockMap.get(var);
    lock.writeLock().lock;
    try {
       // Processing
    } finally {
       lock.writeLock().unlock();
    }
}

You will need to register the different values beforehand. Or you can create them on demand. Again, this might create some huge number of locks which may be prohibitive.

public void writeProcessing(String var) {
    lock = getLockForVar(var);
    ...
}

private ReadWriteLock getLockForVar(String var) {
   ReadWriteLock lock = lockMap.get(var);
    if (lock != null) {
        return lock;
    }
    // this might create an extra lock because of race conditions...
    lock = new ReadWriteLock();
    ReadWriteLock current = lockMap.putIfAbsent(var, lock);
    if (current == null) {
        return lock;
    } else {
        return current;
    }
}

这篇关于Java并发:ReadWriteLock变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 18:12