I am writing a program that utilizes a third party API. I attach a handler to an object and wait for a message back. the responses from the server then get saved into an array list. Unfortunately it takes time for my program to contact the server and so if I make reference to the array list before the server has time to get back to me, my program thinks the list is empty. I've tried multiple different approaches involving threads but so far the only thing that works is just having a pre-set wait time (e.g. 2 seconds).This doesn't seem very elegant and I'm worried might be error prone - if it take more than two seconds some time. Also because my program depends heavily on time efficiency, as you can imagine any wasted time is not good. Are there any better ways of waiting until the ArrayList is populated that you can think of?public class Trader implements IConnectionHandler, Runnable {    static Trader INSTANCE = new Trader();    static int port = 4001;    static int clientId = 0;    JFrame frame = new JFrame(Trader);    Panel panel;    JLabel connectionStatus = new JLabel(Disconnected);    Dimension frameSize;    JTextArea msgBox = new JTextArea();    Logger logger = new Logger(msgBox);    ApiController m_controller = new ApiController(this, logger, logger);    public ArrayList<String> accountList() {        return m_acctList;    }    public ApiController controller() {        return m_controller;    }    public JFrame frame() {        return frame;    }    final ArrayList<String> m_acctList = new ArrayList<String>();    ArrayList<Quotes.Stock> stockList = new ArrayList();    ArrayList<TradeHistory.Completed> tradeList = new ArrayList();    ArrayList<OpenOrders.Orders> ordersList = new ArrayList();    ExecutorService ex = Executors.newFixedThreadPool(1);    public static void main(String[] args) {        INSTANCE.start();    }    public synchronized void start() {        frame.setSize(600, 400);        frameSize = frame.getSize();        panel = new Panel();        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        frame.add(panel);        frame.setVisible(true);        m_controller.connect(null, port, clientId);        try {            wait(1000);        } catch (Exception ex) {            msgBox.append(error with wait);        }        Quotes quotes = new Quotes();        stockList = quotes.stockList;        show(\n);        try {            wait(2000);        } catch (Exception ex) {            msgBox.append(error with wait);        }        msgBox.setText(null);        TradeHistory tradeHistory = new TradeHistory();        tradeList = tradeHistory.tradeHistory;        show(\n);        OpenOrders openOrders = new OpenOrders();        ordersList = openOrders.m_orders;        msgBox.append(Getting Live Orders: \n);        ex.execute(this);        try {            wait();        } catch (Exception ex) {            msgBox.append(error with wait - test\n);        }        ex.shutdown();        for (int i = 0; i < ordersList.size(); i++) {            msgBox.append(Symbol:  + ordersList.get(i).m_contract.symbol() +  Order ID:                     + String.valueOf(ordersList.get(i).m_order.orderId()) +  Action:                     + ordersList.get(i).m_order.action() +  Quantity:                     + ordersList.get(i).m_order.totalQuantity() + \n);        }        try {            wait(2000);        } catch (Exception ex) {            msgBox.append(error with wait);        }        msgBox.setText(null);        Ordering ordering = new Ordering();    }    @Override    public synchronized void run() {        boolean state = true;        while (state == true) {            if (!ordersList.isEmpty()) {                notifyAll();                state = !state;            }        }    }}When I get rid of the executorservice and make wait() into a fixed time, it works fine. But as stated, I'm hoping there is a more elegant way like what I'm trying with threads which will know the moment the appropriate response is received.I'll just show you the OpenOrders class, but all the other classes (Quotes and tradeHistory) work essentially the same way.public class OpenOrders implements ILiveOrderHandler {    ApiController m_controller = Trader.INSTANCE.m_controller;    JTextArea msgBox = Trader.INSTANCE.msgBox;    private HashMap<Long, Orders> m_map = new HashMap<Long, Orders>();    ArrayList<Orders> m_orders = new ArrayList<Orders>();    OpenOrders() {        m_orders.clear();        Trader.INSTANCE.m_controller.reqLiveOrders(this);    }    @Override    public void openOrder(NewContract contract, NewOrder order, NewOrderState orderState) {        Orders full = m_map.get(order.permId());        if (full != null) {            full.m_order = order;            full.m_state = orderState;        } else if (shouldAdd(contract, order, orderState)) {            full = new Orders(contract, order, orderState);            add(full);            m_map.put(order.permId(), full);        }    }    protected boolean shouldAdd(NewContract contract, NewOrder order, NewOrderState orderState) {        return true;    }    protected void add(Orders full) {        m_orders.add(full);    }    @Override    public void openOrderEnd() {    }    @Override    public void orderStatus(int orderId, OrderStatus status, int filled, int remaining,            double avgFillPrice, long permId, int parentId, double lastFillPrice, int clientId,            String whyHeld) {        Orders full = m_map.get(permId);        if (full != null) {            full.m_state.status(status);        }    }    @Override    public void handle(int orderId, int errorCode, String errorMsg) {        throw new UnsupportedOperationException(Not supported yet.); // To change body of                                                                       // generated methods, choose                                                                       // Tools | Templates.    }    static class Orders {        NewContract m_contract;        NewOrder m_order;        NewOrderState m_state;        Orders(NewContract contract, NewOrder order, NewOrderState state) {            m_contract = contract;            m_order = order;            m_state = state;        }    }    static class Key {        int m_clientId;        int m_orderId;        Key(int clientId, int orderId) {            m_clientId = clientId;            m_orderId = orderId;        }    }}
Which would be a more elegant way to make a thread wait?
java;multithreading