我构建的简化版本具有以下内容:
我发现MessageListener线程仅在ExecutorService终止后执行,而不是与它同时运行,即ExecutorService中的线程阻止MessageListener线程运行。这对我来说显然是不可取的。
我想知道是否有人可以向我提供一些指示,说明我的结论是否有效,如果是,为什么?什么是解决它的好方法。
我在下面粘贴了一些半psudeo代码以进一步解释。
public static final int NUM_TASK = 10;
public static final int TIME_OUT = 5000;
public static boolean[] shared_data = new boolean[NUM_TASK];
public static void main(String[] args) throws InterruptedException{
// CREATE the receiver which will be set as an LISTENER for a JMS consumer queue that
// later the tasks in the Executor Service will send request to
setupJMSProducerConsumer();
// CREATE the Executor Service (pool)
ExecutorService fixThreadPoolES = Executors.newFixedThreadPool(10);
List<Future<String>> futures = new ArrayList<Future<String>>();
for(int i = 0; i < NUM_TASK; i++){
// Submit a Callable task to Replay the file
MyTask task = new MyTask(i);
futures.add(fixThreadPoolES.submit(task));
}
// GATHER the result here, based on futures
// gatherResult(futures);
// TERMINATE the ExecutorService
fixThreadPoolES.shutdown();
fixThreadPoolES.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}
private static class MyTask implements Callable<String> {
private static final int WAIT_TIME_SLOT = 1000;
int _idx = -1;
public MyTask (int idx){
_idx = idx;
}
@Override
public String call() throws Exception {
return run();
}
private String run() throws InterruptedException{
// SEND request
// sendRequest(_idx);
// WAIT until the corresponding result in the shared data is set to 'true' by the corresponding LISTENER
int timeWaited = 0;
while (getSharedData(_idx) != true){
timeWaited += WAIT_TIME_SLOT;
Thread.sleep(WAIT_TIME_SLOT);
if (timeWaited > TIME_OUT){
return "Listener timed out, flag not raised, task incompleted for: " + _idx;
}
}
return "Listener raised the flag, task completed for: " + _idx;
}
}
public static class MyMsgReceiver implements MessageListener{
@Override
public void onMessage(Message msg) {
String msgTxt = null;
try {
msgTxt = ((javax.jms.TextMessage) msg).getText();
} catch (JMSException e) {
e.printStackTrace();
return;
}
for (int i = 0; i < NUM_TASK; i++){
if (msgTxt.contains(String.valueOf(i))){
setSharedData(i, true);;
};
}
}
}
private static void setupJMSProducerConsumer(){
com.tibco.tibjms.TibjmsConnectionFactory factory = new com.tibco.tibjms.TibjmsConnectionFactory(TIBCO_URL);
Connection connection = factory.createConnection(TIBCO_USER, TIBCO_PASS);
Session session = connection.createSession(false, 24);
MessageConsumer consumer = session.creatConsumer(session.createQueue(QUEUE_NAME));
MyMsgReceiver receiver = new MyMsgReceiver();
consumer.setMessageListener(receiver);
}
public static synchronized boolean getSharedData(int idx) {
return shared_data[idx];
}
public static synchronized void setSharedData(int idx, boolean val) {
shared_data[idx] = val;
}
答案 0 :(得分:0)
我在你的代码中看到两个错误:
1)您没有同步对shared_data
的访问权限,因此您不会对数组执行原子读取和写入操作,这将导致无法预测的结果。对共享阵列的任何访问都应在synchronized(shared_data) { }
块内,或使用同步getSharedData(int i)
和setSharedData(int i, boolean value)
方法更方便
2)MyTask.run()
中的等待循环也不是正确的。它的实现方式,如果布尔标志不为真,那么任务将系统地等到超时到期,然后报告任务完成,而实际上它并不知道任务完成。
相反,你应该做这样的事情:
long start = System.currentTimeMillis();
long elapsed = 0L;
boolean flag = false;
while (!(flag = getSharedData(_idx)) &&
((elapsed = System.currentTimeMillis() - start) < TIME_OUT)) {
Thread.sleep(1L);
}
if (flag) {
// handle completion
} else {
// handle timeout expired
}