`
songsong
  • 浏览: 11635 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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

分享到:
评论

相关推荐

    httplib库实现非阻塞式监听

    在"httplib实现非阻塞式监听-服务器"的压缩包文件中,可能包含了实现上述功能的示例代码、配置文件或测试脚本。通过研究这些文件,你可以更深入地理解如何在实际项目中运用`httplib`库构建高效的非阻塞式HTTP服务器...

    c++11 实现的阻塞队列

    C++11 实现的阻塞队列 C++11 中的阻塞队列是指在多线程环境下,实现生产者消费者模式的队列。阻塞队列的实现需要解决两个问题:线程安全和阻塞机制。在 C++11 中,我们可以使用 std::mutex、std::condition_...

    设备驱动中阻塞与非阻塞及实现

    在描述中提到的“等待队列”(wait queue)是Linux内核中用于实现阻塞操作的关键数据结构。等待队列以队列的形式存储等待特定事件的进程,这些进程在条件满足之前会被挂起。一旦条件满足,通过调用唤醒函数,如`wake...

    js代码-js -- 实现同步map函数

    5. **性能优化**:同步执行虽然在处理I/O密集型任务时不如异步高效,但如果我们的`map`操作不涉及任何阻塞操作,那么同步版本可能会带来更稳定的性能,因为它不会因为事件循环而跳过或交错任务。 6. **适用场景**:...

    Java开发自学100天,Java开发必背代码 使用Map映射集合实现省市级联选项框功能

    HashMap、TreeMap和LinkedHashMap是常见的Map实现。在本场景中,我们将使用Map来存储省份和对应的城市,其中省份作为键,城市作为值,形成一对多的关系。 1. **Map接口及实现类**: - Map接口定义了基本的操作,如...

    j2me手机端Google map最简单实现

    **J2ME手机端Google Map最简单实现** Java 2 Micro Edition (J2ME) 是一种专门用于小型设备,如手机和平板电脑的Java平台。它允许开发者创建可以在各种不同设备上运行的应用程序。在本教程中,我们将探讨如何在J2ME...

    电子-linux底层驱动中阻塞IO的实现.zip

    本文档“电子-linux底层驱动中阻塞IO的实现.docx”将深入探讨Linux内核中的阻塞I/O(Blocking I/O)机制,特别是与STM32-F0/F1/F2系列微控制器相关的应用。STM32系列是意法半导体(STMicroelectronics)推出的高性能...

    Python实现socket非阻塞通讯功能示例

    这篇文章会详细探讨如何使用Python实现socket非阻塞通信,并结合示例分析其原理、多线程以及客户端和服务器端的具体实现技巧。 首先,了解socket编程的基础概念至关重要。Socket是计算机网络数据传输的基本操作单元...

    map(解决地图找房和海量点卡顿).zip

    本文将深入探讨如何使用"map"技术来解决地图找房过程中遇到的海量数据导致的性能卡顿问题,并结合"vue"框架进行高效开发。我们将讨论以下几个关键知识点: 1. **地图API**:在Web开发中,地图功能通常通过集成地图...

    非阻塞select 实现 socket服务器

    非阻塞select 实现 socket服务器使用select 实现 非阻塞的方式 来实现 服务端

    线程-线程池-锁-集合-Map-队列.docx

    `ConcurrentHashMap`是线程安全的Map实现,适用于多线程环境下的并发访问。 队列是另一种重要的数据结构,Java中的`Queue`接口提供了FIFO(先进先出)的数据结构,常用于线程间的通信或作为线程池的工作队列。`...

    Verilog HDL阻塞赋值工程实现

    **Verilog HDL阻塞赋值工程实现** Verilog HDL是一种硬件描述语言,用于设计数字系统的逻辑。在Verilog中,赋值操作分为阻塞赋值(Blocking Assignment)和非阻塞赋值(Non-blocking Assignment)。理解并正确使用...

    java各个Map的区别.doc

    本文主要探讨了几个常见的 Map 实现类的区别,包括 ConcurrentHashMap、EnumMap 和 HashMap。 1. **ConcurrentHashMap**: 这是一个线程安全的 Map 实现,特别适合在多线程环境中使用。它采用了分段锁的设计,使得在...

    在网页中加载Google Map

    这里,`async`和`defer`属性用于异步加载脚本,避免阻塞页面渲染。`callback=initMap`参数表示当API加载完成时调用`initMap`函数。 现在,我们需要在JavaScript中定义`initMap`函数,这将是初始化地图的入口点。...

    Go 1.9 sync Map 分析图

    1. **并发安全**:`sync.Map`内部实现了锁机制,可以确保在多个goroutine(Go的并发原语)同时访问时的数据一致性。它使用了读写锁(`sync.RWMutex`)来提高并发性能,当多数操作是读取时,允许多个goroutine同时...

    Googlemap_API.rar_GoogleMap_加载地图_地图

    `async`和`defer`属性确保脚本在DOM解析完成后再执行,避免阻塞页面加载。 接着,**地图属性**是指我们可以自定义的一些地图特性。比如,可以改变地图的视图、添加标记、绘制路径、设置图层、启用卫星图或者街景...

    MFC实现非阻塞Socket通信

    本文将深入探讨如何使用MFC实现非阻塞Socket通信,并结合protobuf(Protocol Buffers)作为数据交换格式,构建一个允许多个客户端与单一服务器进行通信的系统。 首先,我们来理解“非阻塞Socket”。在传统的阻塞...

    C++串口通信类(阻塞和非阻塞都支持)

    但在简单应用中,阻塞模式易于实现,代码简洁。 2. 非阻塞模式:非阻塞模式允许程序在等待数据传输时执行其他任务,提高程序的并发性。这种方式需要使用多线程或异步处理机制,以确保程序的运行不会因等待串口操作...

    google map weather

    而"google.map.weather.js"则是实现这一功能的关键代码资源,对于开发者来说,它是探索和构建类似功能的重要参考。理解和掌握这部分知识,有助于我们在Web开发中更好地利用地图服务,提升应用的智能化水平。

Global site tag (gtag.js) - Google Analytics