解决方案 »

  1.   

    其实你只需要对Queue进行读写的部分加锁就可以了,如果是整个客户端读取方法都加锁的话,只要方法执行时间稍长,确实会导致阻塞
      

  2.   

    比如说我们去超市买东西,我们可以在任何一个收款台那里去付款。但是如果超市明明有50个收款台,可是只有一个收款员,这不就是扯淡嘛。有些人可能是受了某些java入门书的毒害,或者某些“说大话”设计模式书籍的毒害,没有必要时也纠缠什么Queue。你的中间件直接就并行地回调客户端注册的回调方法就行了,折腾什么Queue?
      

  3.   

    你要注意,所谓“生产者-消费者”是个最容易扯淡的模式,千万不要模仿。要设计异步程序,一定要直截了当。不要以为一个Queue或者别的什么“消费者”比较低级傻瓜,就模仿。
      

  4.   


    中间件并不是我这里开发的,虽然可以改代码调试,但是我无权改动。
    直接处理回调函数并不是不行,Queue的存在是我为客户端这里加上一层缓冲罢了。
      

  5.   


    中间件并不是我这里开发的,虽然可以改代码调试,但是我无权改动。
    直接处理回调函数并不是不行,Queue的存在是我为客户端这里加上一层缓冲罢了。
    按照sp1234的思路  中间件你无法更改,那在你的客户端,收到数据库,直接封装发布事件,真正处理的地方订阅不处理,类似多个线程同时处理收到的不同数据至于顺序的问题,能不能直接放到数据包中,类似udp通讯那种
      

  6.   

    打个比方说,客户端收到数据,存在队列queue里,然后其他线程读取queue。但是多线程读写就要加锁,而一旦加锁,客户端读取的速度稍慢,就会导致写入部分(回调函数)被锁。
    *********************************************************
    因为有先后顺序,所以用多线程一点作用都没有,所以只能用一个线程处理数据
      _queue = new Queue();
                _queue = Queue.Synchronized(_queue); 这样处理后就不要用代码加锁了
    尝试一下,客户端收到数据就把数据放到queue里  queue.Enqueue,
    这样客户端接收函数处理就足够快了
    开一个threadtiemr线程,queue.Dequeue
    这样肯定不会阻塞客户端 
      

  7.   

    非常感谢大家的回复。
    今天冷静下来,重新考虑客户端的结构,把不必要的旁枝末节都删掉,从头写。
    问题解决掉了(写数据库,写文件都OK)。解决的步骤
    1.因为回调函数是顺序执行的,也就是说只往内存中写数据是不会有问题的。所以用datatable存写库的数据,用arraylist存写文本文件的数据。(不必加锁)
    2.当数据累计到一定程度(比如5000件),用线程池开线程QueueUserWorkItem处理 datatable或者arraylist的副本,然后清空datatable或者arraylist用来继续接收数据。数据的写入和拷贝都在内存中进行,而数据库操作和文件写入都在线程池进行,避免了回调函数的阻塞。为什么一开始不对,是因为原本有一套客户端代码,它开了几个线程用于监视有没有收到数据,而监视线程读取数据的时候就会和回调函数写入产生互斥。把不必要的监视线程去掉,也就豁然开朗了。