quartz执行卡死--强制中断线程

10 篇文章 0 订阅

在quartz中经常会碰到由于网络问题或者一些其他不稳定因素导致的线程卡死问题,这往往会导致数据处理的延时。而有时候一时无法定位到卡死的原因,为了降低系统风险,我们就会希望有一个超时机制,当执行超时时强制中断该操作。下面就举个例子,ftp协议不稳定,当连接ftp上传下载数据时有时候会遇到不可知的因素会导致卡死,比如说主动被动切换,服务器连接数满等等,现在我们使用java提供的动态代理以及Future的超时机制来解决延时问题。代码如下:

public class FtpClientProxy implements InvocationHandler  {
    private static ExecutorService executor = Executors.newCachedThreadPool();
    private FtpClient target;
    private static String interceptorNames="uploadFile,chdir,listFiles,downloadFile,existDir,mkdir,rename";
    private static final  String THREAD_TIMEOUT_CONFIG="THREAD_TIMEOUT_CONFIG";
    private static final  String METHOD_INTERCEPTOR_CONFIG="METHOD_INTERCEPTOR_CONFIG";
    private static int threadTimeout=7200;
    private static final Logger logger=Logger.getLogger(FtpClientProxy.class);
    
    /**    
     * 创建一个新的实例 FtpClientProxy.      
     */
    public FtpClientProxy() {
        try {
            String timeoutConfig=UspcUtil.getSysConfigValue(THREAD_TIMEOUT_CONFIG);
            if(StringUtils.isNotBlank(timeoutConfig)){
                threadTimeout=Integer.parseInt(timeoutConfig);
            }
            interceptorNames=UspcUtil.getSysConfigValue(METHOD_INTERCEPTOR_CONFIG);
        } catch (Exception e) {
            logger.error("获取超时配置THREAD_TIMEOUT_CONFIG出错",e);
        }
       
    }
    
    /**  
     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])    
     */
    @Override
    public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
        Object result = null;
        String methodName=method.getName();
        if(StringUtils.isNotBlank(interceptorNames)&&interceptorNames.contains(methodName)){

            Future<Object> future = executor.submit(new Callable<Object>() {
                
                @Override
                public Object call() throws Exception {
                    logger.debug(method.getName()+"代理方法执行开始");
                    return method.invoke(target, args);
                }
            });
            try {
                result = future.get(threadTimeout, TimeUnit.SECONDS);
                logger.debug(methodName+"代理方法执行结束");
            } catch (TimeoutException e) {
                logger.error("执行方法"+methodName+"超时",e);
                future.cancel(true);
                throw new Exception("执行方法"+methodName+"超时");
            } catch (Exception e) {
                future.cancel(true);// 中断执行此任务的线程
                throw new Exception(e);
            }
        }else{
            result=method.invoke(target, args);
        }
        return result;
    }
    
    /**
     * 绑定委托对象并返回一个代理类
     * 
     * @param target
     * @return
     */
    public FtpClient bind(FtpClient target) {
        this.target = target;
        // 取得代理对象
        return (FtpClient) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass()
                .getInterfaces(), this); 
    }
}

 可以按照配置的时间来进行超时判断,也可以配置拦截的方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值