Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring Executors—在具有特定索引的线程中执行方法_Java_Spring_Implementation - Fatal编程技术网

Java Spring Executors—在具有特定索引的线程中执行方法

Java Spring Executors—在具有特定索引的线程中执行方法,java,spring,implementation,Java,Spring,Implementation,在我的应用程序中,我有一个接收器,它应该使用多个线程处理消息。发送方模块将消息放在堆栈上,接收方模块从该堆栈中获取消息。一切都使用两个线程(一个用于发送,一个用于接收)。现在我想接收多线程的消息 消息具有某种组号。我需要在一个线程中处理一组消息(消息组将多于线程)。我怎么处理这件事 我想这样做: public class ReceiverExample { @Autowired Receiver receiver; @Autowired TaskExecut

在我的应用程序中,我有一个接收器,它应该使用多个线程处理消息。发送方模块将消息放在堆栈上,接收方模块从该堆栈中获取消息。一切都使用两个线程(一个用于发送,一个用于接收)。现在我想接收多线程的消息

消息具有某种组号。我需要在一个线程中处理一组消息(消息组将多于线程)。我怎么处理这件事

我想这样做:

public class ReceiverExample {
    @Autowired
    Receiver receiver; 

    @Autowired 
    TaskExecutor executor;

    public void receive(){
        Msg msg = receiver.receive(); 
        int index = msg.getIndex();

        executor.execute(
                //put index ? ,
                msg
        );
    }
}

我使用的是Spring框架。我知道我必须使用某种遗嘱执行人,但我找不到任何好的例子来说明我的问题

因此,您需要确保具有相同“消息组id”的两个
Runnable
s永远不会并行运行

“executor”接口没有“messageGroupId”的概念,因此您可能需要编写另一个类来协调这一点(不确定第三方库中是否存在类似的内容,也许有人可以发布建议??)

下面的类为每个线程维护一个队列,并将确保具有相同消息组Id的任务始终位于同一队列上。为每个队列创建一个线程来处理任务。。。(这并不完美,但可能是一个很好的起点)


希望这有帮助

谢谢你的想法,它帮助我开发类似的、稍微简单一点的解决方案,效果很好:)
package stack;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MessageGroupTaskExecutor {

    private static final Logger LOG = LoggerFactory.getLogger(MessageGroupTaskExecutor.class);
    private static final long POLL_TIME = 10;

    private BlockingQueue<Runnable>[] queues;
    private Thread[] workerThreads;
    private volatile boolean stopped;
    private ThreadFactory threadFactory;

    public MessageGroupTaskExecutor(int numberOfThreads, ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
        this.queues = new BlockingQueue[numberOfThreads];
        this.workerThreads = new Thread[numberOfThreads];
    }

    public void init() {
        for (int k = 0; k < workerThreads.length; k++) {
            queues[k] = new LinkedBlockingQueue<Runnable>();
            workerThreads[k] = threadFactory.newThread(new WorkerThread(queues[k]));
            workerThreads[k].start();
        }
    }

    /**
     * Not a great impl - no way to "shutdown after all tasks finished" (at the moment...)
     */
    public void shutdown() {
        stopped = true;
        for (Thread thread : workerThreads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                LOG.warn("Interrupted waiting for thread to finish", e);
            }
        }
    }

    public void execute(int messageGroup, Runnable command) {
        queues[messageGroup % queues.length].add(command);
        LOG.debug("Submitted {} for message group {}", command, messageGroup);
    }

    private class WorkerThread implements Runnable {

        private BlockingQueue<Runnable> queue;

        public WorkerThread(BlockingQueue<Runnable> queue) {
            this.queue = queue;
        }

        @Override
        public void run() {
            while (!stopped) {
                Runnable nextJob = null;
                try {
                    nextJob = queue.poll(POLL_TIME, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    LOG.debug("Interrupted when polling queue", e);
                }

                if (nextJob != null) {
                    try {
                        LOG.debug("Got job " + nextJob);
                        nextJob.run();
                        LOG.debug("Completed " + nextJob);
                    } catch (Exception ex) {
                        LOG.debug("Exception thrown by " + nextJob, ex);
                    }
                }
            }
        }
    }
}
package stack;

import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestIt {
    private static final Logger LOG = LoggerFactory.getLogger(TestIt.class);

    public static void main(String[] args) {
        MessageGroupTaskExecutor exe = new MessageGroupTaskExecutor(5, Executors.defaultThreadFactory());

        exe.init();

        for (int k = 0; k < 100; k++) {
            int messageGroup = (int) (Math.random() * 15.0);
            exe.execute(messageGroup, new MyTask(messageGroup, k));
        }
    }

    private static class MyTask implements Runnable {
        private int mg;
        private int taskNumber;

        public MyTask(int mg, int taskNumber) {
            this.mg = mg;
            this.taskNumber = taskNumber;
        }

        @Override
        public void run() {
            LOG.info("Doing task {} for message group {}", taskNumber, mg);
            try {
                Thread.sleep((long) (Math.random() * 500));
            } catch (InterruptedException e) {
            }
            LOG.info("Done task {} for message group {}", taskNumber, mg);
        }

    }
}