阻塞Map BlockingMap的实现

做socket应用用到了BlockingQueue接口,可用于生产者消费者模式,多个线程阻塞着等待queue的数据到来,但是如果是该线程需要等待某个特定的数据该如何处理呢,自己写了个BlockingMap

public interface BlockingMap<V> {

public void put(Integer key, V o) throws InterruptedException;

public V take(Integer key) throws InterruptedException;

public V poll(Integer key, long timeout) throws InterruptedException;

}

public class HashBlockingMap<V> implements BlockingMap<V> {

private ConcurrentMap<Integer, Item<V>> map;

private final ReentrantLock lock = new ReentrantLock();

public HashBlockingMap() {
map = new ConcurrentHashMap<Integer, Item<V>>();
}

public void put(Integer key, V o) throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
if (map.containsKey(key)) {
Item<V> item = map.get(key);
item.put(o);
} else {
Item<V> item = new Item<V>();
map.put(key, item);
item.put(o);
}
} finally {
lock.unlock();
}
}

public V take(Integer key) throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
if (!map.containsKey(key)) {
map.put(key, new Item<V>());
}
} finally {
lock.unlock();
}

Item<V> item = map.get(key);
V x = item.take();
map.remove(key);

return x;
}

public V poll(Integer key, long timeout) throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
if (!map.containsKey(key)) {
map.put(key, new Item<V>());
}
} finally {
lock.unlock();
}

Item<V> item = map.get(key);
V x = item.poll(timeout);
map.remove(key);

return x;
}

private static class Item<E> {

private final ReentrantLock lock = new ReentrantLock();

private final Condition cond = lock.newCondition();

private E obj = null;

private void put(E o) throws InterruptedException {
if (o == null)
throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
obj = o;
cond.signal();
} finally {
lock.unlock();
}
}

E take() throws InterruptedException {
E x;
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (obj == null) {
cond.await();
}
} catch (InterruptedException ie) {
cond.signal();
throw ie;
}
x = obj;
} finally {
lock.unlock();
}
return x;
}

private E poll(long timeout) throws InterruptedException {
timeout = TimeUnit.MILLISECONDS.toNanos(timeout);
E x;
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
if (obj != null) {
x = obj;
break;
}
if (timeout <= 0) {
return null;
}
try {
timeout = cond.awaitNanos(timeout);
} catch (InterruptedException ie) {
cond.signal();
throw ie;
}
}
} finally {
lock.unlock();
}
return x;
}

}

}

// 消费者根据sequence取得自己想要的对象
Response response = blockingMap.poll(sequence, timeout);
// 生产者
blockingMap.put(response.getSequence(), response);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的Map是一种键值对的数据结构,它提供了快速的访问和查找功能。但是,Map并不是一个阻塞队列,它不能直接用来实现阻塞队列功能。但是,我们可以使用Map实现一个阻塞队列,具体实现方法如下: 1. 创建一个Map对象,用来存储队列元素。 2. 创建一个互斥锁对象,用来保证队列操作的线程安全。 3. 创建两个条件变量,一个用来表示队列已满,另一个用来表示队列为空。 4. 实现队列的put方法,当队列已满时,阻塞当前线程,等待队列有空闲位置。 5. 实现队列的take方法,当队列为空时,阻塞当前线程,等待队列有元素可取。 6. 实现队列的size方法,返回队列中元素的数量。 下面是一个使用Map实现阻塞队列的示例代码: ``` import java.util.Map; import java.util.HashMap; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class BlockingQueue<T> { private final Map<Integer, T> map; private final Lock lock; private final Condition notFull; private final Condition notEmpty; private int capacity; private int head; private int tail; public BlockingQueue(int capacity) { this.capacity = capacity; map = new HashMap<>(capacity); lock = new ReentrantLock(); notFull = lock.newCondition(); notEmpty = lock.newCondition(); head = 0; tail = 0; } public void put(T element) throws InterruptedException { lock.lock(); try { while (tail - head == capacity) { notFull.await(); } map.put(tail % capacity, element); tail++; notEmpty.signal(); } finally { lock.unlock(); } } public T take() throws InterruptedException { lock.lock(); try { while (tail == head) { notEmpty.await(); } T element = map.remove(head % capacity); head++; notFull.signal(); return element; } finally { lock.unlock(); } } public int size() { lock.lock(); try { return tail - head; } finally { lock.unlock(); } } } ``` 在这个示例代码中,我们使用了一个Map来存储队列元素,并使用了一个互斥锁和两个条件变量来实现阻塞队列的功能。put方法和take方法分别实现了向队列中添加元素和从队列中取出元素的功能。size方法返回队列中元素的数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值