如上所述,数据队列读取超时是服务器端的。如果 iSeries 和客户端之间的 TCP 连接停止或断开,客户端将等待套接字超时。我的解决方案是建立一个故障安全中断器来阻止停滞的读取。这是如何完成此操作的快速代码示例。
public class DataQueueListenerExample {
//This executes our Interrupter after the specified delay.
public final ScheduledThreadPoolExecutor interruptExecuter = new ScheduledThreadPoolExecutor(1);
//the dataqueue object.
protected DataQueue dataqueue;
public DataQueueEntry read(int wait)
{
ScheduledFuture<?> future = null;
try {
//create our fail safe interrupter. We only want it to
//interrupt when we are sure the read has stalled. My wait time is 15 seconds
future = createInterrupter(wait * 2, TimeUnit.SECONDS);
//read the dataqueue
return this.dataqueue.read(wait);
} catch (AS400SecurityException e) {
} catch (ErrorCompletingRequestException e) {
} catch (IOException e) {
} catch (IllegalObjectTypeException e) {
} catch (InterruptedException e) {
//The read was interrupted by our Interrupter
return null;
} catch (ObjectDoesNotExistException e) {
} finally{
//Cancel our interrupter
if(future != null && !future.isDone())
future.cancel(true);
Thread.interrupted();//clear the interrupted flag
interruptExecuter.shutdown();
}
return null;
}
public ScheduledFuture<?> createInterrupter(long timeout,TimeUnit timeunit)
{
return interruptExecuter.schedule(new Interrupter(),timeout,timeunit);
}
class Interrupter implements Runnable
{
final Thread parent;
Interrupter()
{
this.parent = Thread.currentThread();
}
@Override
public void run() {
parent.interrupt();
}
}
}
我强烈建议在出现 InterruptedException 后在新的 AS400 连接上重新创建 DataQueue 对象。您的 AS400 连接可能会停止。Thread.interrupt 非常有用,但请谨慎使用。