【问题标题】:Usage Of Executor Thread PoolExecutor线程池的使用
【发布时间】:2018-11-09 06:30:59
【问题描述】:

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

但我对使用如下执行线程感到困惑。当我在 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();
}

【问题讨论】:

  • 嘿,我不知道为什么,但是您的代码似乎难以理解(您编辑/复制它的方式)。 “将执行程序从 for 循环中取出”是什么意思?您正在使用 for 循环来激活所有线程,不是吗?
  • 我的意思是我想使用 ExecutoreService 在池中创建线程,并在将对象插入队列时使用池中的一个线程。一个队列对象一个线程
  • 为什么不提交要执行的任务,而不是在队列中添加一些对象然后读取呢?
  • 如果所有线程都在向其他地方发送消息怎么办?我需要将它们放入队列以提高可靠性和性能。否则速度会变慢?我说的对吗?
  • Executors 维护着一个提交作业的队列,除非你有充分的理由这样做,否则我不建议你尝试实现 executor。

标签: java multithreading


【解决方案1】:

这将为您创建一个您传递的大小的线程池。

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);

我相信基于此,您可以重新设计您正在实施的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-16
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 2018-06-28
    • 1970-01-01
    相关资源
    最近更新 更多