侦听jms队列,一次只处理10条消息

时间:2015-09-14 21:05:31

标签: java multithreading jms

我有一个javax.jms.Queue队列,让我的监听器监听这个队列。我得到消息(一个字符串)并执行一个进程,将该字符串作为输入参数传递给该进程。

我想一次运行该进程的10个实例。完成后,只应处理下一条消息。

如何实现?因为它一次读取所有消息并运行该进程的多个实例,导致服务器被挂起。

// using javax.jms.MessageListener
message = consumer.receive(5000); 
if (message != null) { 
    try { 
        handler.onMessage(message);  //handler is MessageListener instance
    }
}

3 个答案:

答案 0 :(得分:1)

尝试将此注释放在mdb侦听器上:

@ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10")

答案 1 :(得分:0)

我认为简单的while检查就足够了。这是一些Pseudocode。

While (running processes are less than 10) {
    add one to the running processes list
    do something with the message
}

以及onMessage的代码:

function declaration of on Message(Parameters) {
    do something
    subtract 1 from the running processes list
}

确保您用于计算正在运行的进程数量的变量被声明为volatile

请求示例:

public static volatile int numOfProcesses = 0;

while (true) {
    if (numOfProcesses < 10) {
        // read a message and make a new process, etc
        // probably put your receive code here
        numOfProcesses++;
    }
}

无论您的流程代码是在哪里写的:

// do stuff, do stuff, do more stuff
// finished stuff
numOfProcesses--;

答案 2 :(得分:0)

我假设您有办法接受来自外部流程的hasTerminated条消息。此控制器线程将使用Semaphore与JMS侦听器通信。 Semaphore初始化为10个许可,每次外部进程调用TerminationController#terminate(或者外部进程与侦听器进程通信)时,它会向Semaphore添加许可,然后JMSListener必须首先获得许可才能调用messageConsumer.release(),以确保一次只能激活10个进程。

// created in parent class
private final Semaphore semaphore = new Semaphore(10);

@Controller
public class TerminationController {
    private final semaphore;

    public TerminationController(Semaphore semaphore) {
        this.semaphore = semaphore;
    }

    // Called from external processes when they terminate
    public void terminate() {
        semaphore.release();
    }
}

public class JMSListener implements Runnable {
    private final MessageConsumer messageConsumer;
    private final Semaphore semaphore;

    public JMSListener(MessageConsumer messageConsumer, Semaphore semaphore) {
        this.messageConsumer = messageConsumer;
        this.semaphore = semaphore;
    }

    public void run() {
        while(true) {
            semaphore.acquire();
            Message message = messageConsumer.receive();
            // create process from message
        }
    }
}