gch_h
2011-01-05 16:38 阅读 277
已采纳

有关jms中单线程的问题

因项目急需,小弟最近在学习jms,使用了ibm Mq队列服务器,有个问题请教大家
先谢!
在消息队列的接收端onMessage方法被调用时要求:当上一次onMessage没有执行完成时,不能执行下一次onMessage操作,
也就是对于一个队列来说,它不能并发执行多个onMessage方法。
我的问题时默认情况下onMessage是不是并发执行的,有什么办法能改变它并发或者串行执行?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

4条回答 默认 最新

  • 已采纳
    beneo beneo 2011-01-06 11:03

    [code="java"]public synchronized void onMessage() {
    }
    [/code]

    如果这个不行

    你就
    [code="java"]
    public void onMessage(message) {
    synchronized(this.getClass) {
    }
    }
    [/code]

    点赞 评论 复制链接分享
  • lang_shao lang_shao 2011-01-05 16:39

    [code="java"]
    public synchronized void onMessage() {
    }
    [/code]
    加个 synchronized 就可以了

    点赞 评论 复制链接分享
  • beneo beneo 2011-01-05 16:55

    [quote]在消息队列的接收端onMessage方法被调用时要求:当上一次onMessage没有执行完成时,不能执行下一次onMessage操作,
    也就是对于一个队列来说,它不能并发执行多个onMessage方法。
    我的问题时默认情况下onMessage是不是并发执行的,有什么办法能改变它并发或者串行执行?[/quote]

    [code="java"]
    private ArrayBlockingQueue queue = new xxxx;

    private ExecutorService executor = Executors.newFix......

    xxListen() {
    start();
    }

    private void onMessage(message) {
    queue.add(message);
    }

    private void start() {
    message = null;
    while((message = queue.take()) != null) {
    executor.executor(new Runnable(){
    public void run() {
    //这里用来处理
    }
    });
    }
    }

    [/code]

    以上代码的好处是
    1. 你把onMessage的消息全部缓存在你的服务器里面,这样,jms broker就不会阻塞

    1. 你可以通过queue来控制消息进入的数量

    2. 异步处理queue里面的消息,就算处理的时候抛异常,线程也传建一个新的。

    你想同步处理,在Executors.newFiexThreadPool(1),如果想几个同步处理,就把1便成2或者N好了

    实现非常简单

    点赞 评论 复制链接分享
  • beneo beneo 2011-01-06 10:07

    [code="java"]轮询的方法已经否决了,因为长时间运行占用资源太大,而且还有导致服务器死机的风险,[/code]

    [code="java"] while((message = queue.take()) != null) { [/code]

    queue.take()如果没有数据会阻塞,

    [quote]因为长时间运行占用资源太大,而且还有导致服务器死机的风险[/quote] 你这个说法有没有依据呢,你比较一下ThreadPoolExecutor的源代码

    [quote]还有你的代码是多线程的,另外你的循环停止后没办法再次启动[/quote]
    我是多线程的,我不知道有什么场景需要这个循环停止?如果认为停止,你可以在循环前面加上一个flag

    如果说这个里面处理挂了,那你就不了解ExecutorService的工作原理,如果线程挂了的话,会有新的线程补进来的。不用担心异常
    [code="java"]
    message = null;

    while((message = queue.take()) != null) {

    executor.executor(new Runnable(){

    public void run() {

    //这里用来处理

    }

    });

    }

    [/code]

    点赞 评论 复制链接分享

相关推荐