kitsuneFox
kitsuneFox

Reputation: 1271

executor not executing threads from within a main thread

I have a Thread which runs always with while(true) loop and basically all it does is to add Runnable objects to an executor.

OrderExecutionThread:

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

I'm running this thread By doing this in my main class:

new Thread(orderExecutionThread).start();

The executor suppose to execute the OrderExecution runnable object which does this:

@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();
            }
        }

    }

I know for sure that both lists are not empty and the initAndRunExecution is being called, however the order execution run method is not being called....

Upvotes: 0

Views: 269

Answers (1)

Gray
Gray

Reputation: 116878

I know for sure that both lists are not empty and the initAndRunExecution is being called, however the order execution run method is not being called....

I suspect that this is a problem because your firstSellsList and firstBuysList are not synchronized collections. I suspect that other threads are adding to those lists but your OrderExecutionThread never sees the memory updates so just spins forever seeing empty lists. Whenever you share data between threads you need to worry about how the updates will be published and how the thread cache memory will be updated.

As @Fildor mentions in the comments, one solution would be to use a BlockingQueues instead of your Lists. The BlockQueue (for example LinkedBlockingQueue) is a synchronized class so this takes care of the memory sharing. An alternative benefit is that you don't have to do a spin-loop to watch for entries.

For example, your OrderExecutionThread might do something like:

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

This will wait until the lists get entries before running the orders.

Upvotes: 1

Related Questions