设置在添加第一个元素时触发事件,或者删除最后一个元素

时间:2018-01-05 10:47:40

标签: java concurrency

我有一个允许用户收听网络事件的API。我想在添加第一个事件侦听器时启动网络连接,并在删除最后一个侦听器时断开连接。

属性:

  • 读取集合(侦听器)的次数比写入的次数多。
  • 我需要能够从多个线程同时修改和读取集合。
  • 我需要在添加第一个元素(连接到网络)时以及删除最后一个元素(断开网络连接)时触发事件。

到目前为止我看过的内容:

  • CopyOnWriteArraySet:针对阅读进行优化的线程安全集,而不是写入。添加第一个元素或删除最后一个元素时,没有运行操作的机制。
  • Phaser:在删除最后一个元素时触发事件,但在添加第一个元素时不触发。我想我可以使用两个Phasers来实现这种行为,但这似乎很浪费。

1 个答案:

答案 0 :(得分:0)

也许ReadWriteLock对你有好处?

  

ReadWriteLock维护一对关联的锁,一个用于只读操作,另一个用于写入。只要没有写入器,读锁定可以由多个读取器线程同时保持。写锁是独占的。

简单示例(我使用hashmap代替设置):

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class LockWrapper {

private final ReadWriteLock readWriteLock;
private final Map<Integer, Object> map;
private final EventSender sender;

public LockWrapper(EventSender eventSender) {
    map = new HashMap<>();
    readWriteLock = new ReentrantReadWriteLock();
    sender = eventSender;
}

public void add(Object o) {
    readWriteLock.writeLock().lock();
    if (map.isEmpty()) {
        sender.send("First add");
    }
    map.put(o.hashCode(), o); // for example using hashcode for key
    readWriteLock.writeLock().unlock();
}

public void remove(Object o) {
    readWriteLock.writeLock().lock();
    map.remove(o.hashCode());

    if (map.isEmpty()) {
        sender.send("remove last");
    }
    readWriteLock.writeLock().unlock();
}

public Object read(int key) {
    readWriteLock.readLock().lock();
    Object object = map.get(key);
    readWriteLock.readLock().unlock();
    return object;
}}