我正在执行程序线程池上检查是否有任何对象已插入到阻塞队列中。如果队列中有任何对象,则有一个线程从池中唤醒,并从队列中获取对象,然后将其发送到某个类进行处理。

但是我对使用以下执行程序线程感到困惑。当我在for循环中使用它们时,进程可以按我预期的那样快速运行,但是看起来有些错误。当我将执行程序从for循环中移出时,过程会变慢。这个逻辑正确吗?

休息课

@RestController
public class FraudRestController {

    @Autowired
    private CoreApplication core;

//LOGIC HERE
....

core.addMesageToQueue(rbtran, type);

}


消息添加到队列

public static void addMessageToQueue(TCPRequestMessage message) throws InterruptedException {
        jobQueue.put(message);
    }


执行程序线程在核心类中侦听队列

ExecutorService consumers = Executors.newFixedThreadPool(THREAD_SIZE);
//Core Inits in here
    @PostConstruct
    public void init() {
        //LOGIC
        ...
        //<---THIS BLOCK----->
        for (int i = 0; i < THREAD_SIZE; i++) { //<---- This For Loop
            consumers.submit(() -> {
                while (true)
                    sendMessageToServer();
            });
        }
        //<---THIS BLOCK----->
    }


发送消息功能

private void sendMessageToServer() throws Exception {
//LOGIC
...
    if (host.isActive()) {
        TCPRequestMessage message = jobQueue.take();
}

最佳答案

这将为您创建一个与您通过的大小相同的线程池。

ExecutorService consumers = Executors.newFixedThreadPool(THREAD_SIZE);


这意味着现在队列中有THREAD_SIZE个线程正在等待。创建的此队列是LinkedBlockingQueue。此队列具有以下属性:如果线程为空或已满,则使线程等待它。

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}


如果将任务提交到池中,则此时队列已满,则不会提交任务。在我们的案例中,由于我们没有提及尺寸,因此此处的尺寸为Integer.MAX_VALUE

如果队列为空,则池中的线程将等待将任务插入队列中。
调用ExecutorService的Submit方法时。
在内部,任务被提交到LinkedBlockingQueue的队列boolean offer(E e);中。

我相信基于此,您可以重新设计您要实现的内容。

07-24 09:38
查看更多