阻塞Map BlockingMap的实现

阅读更多
做socket应用用到了BlockingQueue接口,可用于生产者消费者模式,多个线程阻塞着等待queue的数据到来,但是如果是该线程需要等待某个特定的数据该如何处理呢,自己写了个BlockingMap
public interface BlockingMap {
	
	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 implements BlockingMap {

	private ConcurrentMap> map;
	
	private final ReentrantLock lock = new ReentrantLock();

	public HashBlockingMap() {
		map = new ConcurrentHashMap>();
	}

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

		Item 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());
			}
		} finally {
            lock.unlock();
        }

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

		return x;
	}

	private static class Item {

		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);

你可能感兴趣的:(IE,Socket)