需要在web应用中定义一个全局的消息队列,同一时间只能有一个线程操作它,(put,get),有没有好的类,或者是该怎么实现?

解决方案 »

  1.   

    用ConcurrentHashMap就好,key就是你的值,value给一个空串就行
      

  2.   

    楼上的已经解决了。API里面有的东西,没必要自己再去实现
      

  3.   

    你的jdk是什么版本的,如果是1.5以上的版本,可以尝试一下:import java.util.concurrent.PriorityBlockingQueue;
    里面的锁机制不在是原始的synchronized而是,lock方式,更加适合于多线程高并发访问中锁带来的性能开销。其实如果你仅仅是为了操作上锁住,自己加一个锁也是无所谓的;但是synchronized在面对高并发的时候,会出现极大的性能开销,所以在现在java应用中都是用乐观加锁机制;另外在较高版本的jdk中,这些集合类,java也提供了对一个对象由于锁问题导致的阻塞问题,尤其是很多时候读相互之间是没有必要阻塞的或者写的同时没有必要阻塞读(这在很多应用中是成立的),这个时候,java提供了一种多版本拷贝的方法,这个设计思想来源于数据库架构中的一种回退段的方向用法,它会将数据拷贝修改成脏数据后,然后会对原来数据做一个原子性的拷贝工作,在整体的应用中也可以酌情考虑选择。
    有些时候锁多了未必好,所以可以适当考虑自己锁的粒度是如何的,在适当的应用场景我们是尽量做到无锁,那是最好的,而这里面更多的是需要参与到设计中,涉及到更多的模型,其实就我个人在非常繁复的应用中,而且对性能要求很高的情况下,我宁愿自己写一个,来使得性能达到理想的情况;当然锁是最简单、最安全的,不过它的开销也是最大的。举个简单例子说明下:当你发起一个遍历操作,这个遍历操作需要遍历一万个元素,是否遍历过程中所有数据都不允许访问和修改?这个开销也太大了吧,这个好比是一个人在食堂吃饭,就不允许其他所有人吃饭一样,至少其他餐桌还可以用吧,其实修改的时候只要在拷贝一份数据在其他地方修改即可,等这边遍历完成后,拷贝回来就OK了;而读操作也是可以同时发生的。共享队列去获取的过程中,如果是双机通信可以采用IBM MQ技术;不过你可以自己编写了,我至少会在这个基础上去做一个hash散列,再做一个向量状态控制;比如:读取数据放入队列中的并不是传统的队列模式,而是一种每个节点上会有一批数据,这样锁在第一层会减少很多,而且减少频繁访问带来的开销,一次处理多个数据;第二是按照数据做垂直切割,即将数据按照某种散列方式进行分割,如果是数字可以直接按照线程数取模法则,如果是字符串可以采用hash散列,当然还有其他的方法;每个线程根据自身的编号只需要操作自己的数据信息,没有锁;而状态位控制是如何呢?这边读信息放入队列的线程放入完成后,就将状态位置为数据存在状态,而处理线程发现这个数据存在就去取一个向量出来(这里指取走多个数据,队列中每个节点都是一个向量),再将状态位置为我已经取走了,你又可以去读些数据到向量中了;对于单生产者、单消费者情况就无需用到锁了。只需要将做逻辑队列,在一个较长的数组中作轮训,前者跑,后者追,在下标处理上使用一下轻量级的volatile即可,C++不需要处理。如果对无锁有兴趣的话,可以多多交流,我在一篇文章中有一部分写到了无锁相关内容,有兴趣可以看看(该文第11章):
    http://blog.csdn.net/xieyuooo/archive/2011/05/15/6421294.aspx