【问题标题】:executor not executing threads from within a main thread执行程序不从主线程中执行线程
【发布时间】:2017-06-19 06:19:12
【问题描述】:

我有一个线程,它始终使用while(true) 循环运行,基本上它所做的只是将 Runnable 对象添加到执行程序。

订单执行线程:

public class OrderExecutionThread extends Thread implements Runnable {
    final private static int ORDER_EXEC_THREADS_NUMBER = 10;
    private boolean running = true;
    private boolean flag = true;

    private List<Order> firstSellsList = new ArrayList<>();
    private List<Order> secondSellsList = new ArrayList<>();

    private ManagedDataSource managedDataSource;
    private ExecutorService executorService;

    public OrderExecutionThread(ManagedDataSource managedDataSource) {
        this.managedDataSource = managedDataSource;
        this.executorService = Executors.newFixedThreadPool(ORDER_EXEC_THREADS_NUMBER);
    }

@Override
    public void run() {
        while (running) {
            if (!firstSellsList.isEmpty() && !firstBuysList.isEmpty()) {
                initAndRunExecution(firstBuysList.get(0), firstSellsList.get(0));
        }

    }

    private void initAndRunExecution(Order buy, Order sell) {
        executorService.submit(new OrderExecution(buy, sell, managedDataSource));
    }
}

我正在运行这个线程通过在我的主类中执行此操作:

new Thread(orderExecutionThread).start();

执行者假设执行 OrderExecution runnable 对象:

@Override
    public void run() {
        try {
            connection = managedDataSource.getConnection();
            makeExecution(sell, buy);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (!connection.isClosed())
                    connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

我确定这两个列表都不为空,并且正在调用 initAndRunExecution,但是没有调用 order execution run 方法....

【问题讨论】:

  • 尝试firstBuysList.remove(0) 而不是firstBuysList.get(0)。 firstSells 相同 ...get 不会删除该元素。因此,您处于无限循环中,以非常高的频率提交相同的两个元素。所以我怀疑你的 Executor-threads 根本就不会被安排。
  • @Fildor,删除效果不佳...
  • 哦,我明白了。删除了我的评论。您如何填写这些列表?
  • 在您的OrderExecutionThread 中,您有secondSellsList,但没有firstBuysList。这只是一个错字(而不是secondSellsList 问题的代码sn-p 应该是firstBuysList)?或者您在此代码块之外有firstBuysList,但在OrderExecutionThread 中可见?
  • @Gray 是的,没错。重新考虑这一点,您的建议似乎更合理。我想睡眠只是以某种方式导致主线程最终看到数据更新。我得出了错误的结论。

标签: java multithreading


【解决方案1】:

我确定这两个列表都不为空,并且正在调用 initAndRunExecution,但是没有调用订单执行运行方法....

我怀疑这是一个问题,因为您的 firstSellsListfirstBuysList 不是同步集合。我怀疑其他线程正在添加到这些列表中,但是您的 OrderExecutionThread 永远不会看到内存更新,所以只会永远旋转看到空列表。每当您在线程之间共享数据时,您都需要担心更新将如何发布以及线程缓存内存将如何更新。

正如@Fildor 在 cmets 中提到的,一种解决方案是使用 BlockingQueues 而不是您的 Lists。 BlockQueue(例如LinkedBlockingQueue)是一个同步类,因此它负责内存共享。另一个好处是您不必执行自旋循环来监视条目。

例如,您的 OrderExecutionThread 可能会执行以下操作:

private final BlockingQueue<Order> firstBuys = new LinkedBlockingQueue<>();
private final BlockingQueue<Order> firstSells = new LinkedBlockingQueue<>();

while (!Thread.currentThread().isInterrupted()) {
    // wait until we get a buy
    Order buy = firstBuys.take();
    // wait until we get a sell
    Order sell = firstSells.take();
    initAndRunExecution(buy, sell);
}

这将等到列表获得条目后再运行订单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 2023-03-04
    • 1970-01-01
    相关资源
    最近更新 更多