Java 执行器不在主线程内执行线程
我有一个线程总是运行Java 执行器不在主线程内执行线程,java,multithreading,Java,Multithreading,我有一个线程总是运行while(true)循环,它所做的基本上就是向执行器添加可运行的对象 OrderExecutionThread: public class OrderExecutionThread extends Thread implements Runnable { final private static int ORDER_EXEC_THREADS_NUMBER = 10; private boolean running = true; private bo
while(true)
循环,它所做的基本上就是向执行器添加可运行的对象
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));
}
}
执行器假设执行执行执行以下操作的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方法
我确信这两个列表都不是空的,并且正在调用initAndRunExecution,但是没有调用order-execution-run方法
我怀疑这是一个问题,因为您的firstSellsList
和firstBuysList
不是同步的集合。我怀疑其他线程正在添加到这些列表中,但是您的OrderExecutionThread
从未看到内存更新,所以只需旋转就可以看到空列表。每当在线程之间共享数据时,您都需要担心更新将如何发布以及线程缓存内存将如何更新
正如@Fildor在评论中提到的,一种解决方案是使用阻塞队列
s而不是您的列表
s。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);
}
private final BlockingQueue firstBuys=new LinkedBlockingQueue();
private final BlockingQueue firstSells=新建LinkedBlockingQueue();
而(!Thread.currentThread().isInterrupted()){
//等我们买到东西再说
订单购买=首次购买。购买();
//等我们卖了再说
订单销售=首次销售。take();
初始化和运行执行(购买、出售);
}
这将等待列表获得条目后再运行订单。尝试
firstBuysList。删除(0)
而不是firstBuysList.get(0)
。Firstseals也一样<代码>获取不会删除元素。所以你在一个无休止的循环中,以非常高的频率提交相同的两个元素。所以我怀疑你的执行线程根本就没有计划好。@Fildor,remove不能正常工作……哦,我明白了。删除了我的评论。如何填写这些列表?在您的OrderExecutionThread
中,您有secondSellsList
,但没有firstBuysList
。这是否只是一个输入错误(而不是问题中的secondSellsList
代码片段应该是firstBuysList
)?或者您的firstBuysList
位于此代码块之外,但在OrderExecutionThread
中可见?@Gray是的,没错。重新考虑一下,你的建议似乎更有道理。我猜睡眠只是以某种方式导致主线程最终看到数据更新。我得出了错误的结论。
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);
}