2013-05-01 29 views
6

当使用JTOpen的KeyedDataQueue类提供的read()方法时,我发现了一个奇怪的行为。JTOpen KeyedDataQueue read()timeout

我已经设置了90s的超时时间,当超时达到99%的读执行时,我的调用方法执行恢复。

至于其他1%超时不被视为/到达,我调用方法撑挂...

搜索了一下后,我发现这个帖子:

http://archive.midrange.com/java400-l/201112/msg00056.html

基本上它证实了我的猜测:

“我还发现,DataQueue.read()超时功能 服务器端,所以如果在TCP/IP康恩ection被无声地拆除(我相信这是它的根本原因),它仍然会挂起。 “

我使用JTOpen的7.2版本,我意识到版本7.9已经在那里。我没有,因为我有使用7.2很多关键应用的是稳定的,并更新到7.9真的,这是第一个真正的场景,让我考虑更新到7.9.

为了帮助我做出这个决定,我真的很希望你的反馈,尤其是那些遇到这种情况的你,并且最终通过升级JTOpen来解决它。

具体来说,是否有解决这个问题的方法,并且升级JTOpen帮助这个问题?将JTOpen升级到7.9中断任何在7.2中工作的东西?

+0

@JamesA:我是拼写自己的标尺,但没有必要美化所有的东西。 ;)(不过这是一个很好的编辑。) – 2013-05-02 13:37:41

+1

您找到了[Midrange.com上的Java400列表](http://lists.midrange.com/mailman/listinfo/java400-l)的链接;你可能想注册该邮件列表并在那里发布你的问题。看来到目前为止,与Midrange.com相比,IBM中端社区对Stack Overflow的参与度非常薄。 – 2013-05-02 16:14:06

+0

也许是因为他们的拼写能力差:P我会在那里尝试我的运气 – RedEagle 2013-05-03 00:07:48

回答

1

如上所述,dataqueue读取超时是服务器端。如果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非常有用,但请谨慎使用。

+0

这几乎是正确的......这段代码成功地达到了InterruptedException,但是使用VisualVM,我意识到线程正在被挂起......我认为这是因为DataQue的读取方法仍然活跃......任何想法?有没有办法将它设置为已读? – RedEagle 2014-08-05 09:13:27

+0

只需要添加interruptExecuter.shutdown();谢谢Zig158 – RedEagle 2014-08-05 09:56:36