监控函数的执行时间,若超时则强制返回一个默认值

这篇博客介绍了如何监控函数的执行时间,当超过预设时间时,函数会强制返回一个默认值,并使用`Thread.interrupt()`方法来尝试结束阻塞。示例中包含`Worker.java`, `WorkThread.java`和`MonitorThread.java`三个关键组件,通过反射实现通用性,追求效率的读者可以考虑去除反射部分。" 127694089,2254003,Flink CEP实战:构建智能监控与实时分析,"['flink', '大数据', '实时分析', '风控系统', '异常检测']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     这里的函数强制返回是指在函数调用处结束阻塞,返回一个默认值, 同时调用执行函数线程的interrupt()方法,程序解除阻塞但不保证能能够结束函数的执行(参见API Thread的interrupt()方法)。为了更通用一点用了反射,如果对效率非常敏感,可自行修改去掉反射部分。

Worker.java:

/**
 * 监控函数执行时间,若超时强制返回
 * 
@author Liw
 * @time 2007-6
 
*/


public class Worker 
{
    
/**
     * 
@param methodName 函数名
     * 
@param defaultValue 默认值。若为基本类型则需转换为其包装类,如int类型的1需转换成new Integer(1)
     * 
@param timeout 超时时间
     * 
@param currentObj 要执行函数的对象
     * 
@param paramValues 参数值
     * 
@param primitiveTypeIndex 基本数据类型在参数列表中的索引,下表从0开始
     * 
@return 函数返回值
     
*/

    
public Object work(String methodName, Object defaultValue, long timeout, Object currentObj, Object[] paramValues, int[] primitiveTypeIndex)
    
{
        
if (paramValues == null{
            paramValues 
= new Object[]{};
        }

        
if (primitiveTypeIndex == null{
            primitiveTypeIndex 
= new int[]{};
        }

        
        MonitorThread monitor 
= new MonitorThread(defaultValue, timeout);
        WorkThread worker 
= new WorkThread(monitor, currentObj, methodName, paramValues, primitiveTypeIndex);
        
        worker.start();
        monitor.start();
        
        monitor.waitFor();
        
        
if (worker.isAlive()) {
            worker.interrupt();
        }

        
if (monitor.isAlive()) {
            monitor.interrupt();
        }

        
        
return monitor.getResult();
    }

}

 

WorkThread.java:

/**
 * 执行函数的线程
 * 
@author Liw
 * @time 2007-6
 
*/


import java.lang.reflect.Method;

public class WorkThread extends Thread
{
    MonitorThread monitor;
    String methodName;
    Object[] paramValues;
    Class[] paramClasses;
    Object currentObj;
    
    
/**
     * 
@param monitor 监视此线程的线程
     * 
@param currentObj 执行函数的对象
     * 
@param methodName 函数名
     * 
@param paramValues 参数值
     * 
@param primitiveTypeIndex 函数参数中基本数据类型的索引,下标从0开始
     
*/

    
public WorkThread(MonitorThread monitor, Object currentObj, String methodName, Object[] paramValues, int[] primitiveTypeIndex)
    
{
        
this.monitor = monitor;
        
this.methodName = methodName;
        
this.paramValues = paramValues;
        
this.currentObj = currentObj;
        paramClasses 
= new Class[paramValues.length];
        
        
//得到参数的类型
        for (int i = 0; i < primitiveTypeIndex.length; i++{
            
try {
                paramClasses[primitiveTypeIndex[i]] 
= (Class)(paramValues[primitiveTypeIndex[i]].getClass().getDeclaredField("TYPE").get(null));
            }
 catch (Exception e) {
                e.printStackTrace();
            }

        }

        
for (int i = 0; i < paramValues.length; i++{
            
if (paramClasses[i] == null{
                paramClasses[i] 
= paramValues[i].getClass();
            }

        }

        
        
this.setDaemon(true);  //标记为守护线程,不阻止程序退出
    }

    
    
public void run()
    
{
        Method method 
= null;
        
try {
            method 
= currentObj.getClass().getDeclaredMethod(methodName, paramClasses);
            Object value 
= method.invoke(currentObj, paramValues);
            monitor.setResult(value);
        }
 catch (Exception e) {
            e.printStackTrace();
        }

    }

}

 

MonitorThread.java:

/**
 * 监控函数执行时间
 * 
@author Liw
 * @time 2007-6
 
*/


public class MonitorThread extends Thread 
{
    
private boolean flag;
    
private Object result;  //函数返回值
    private long timeout;
    
    
/**
     * 
@param defaultResult 默认返回值
     * 
@param timeout 超时时间
     
*/

    
public MonitorThread(Object defaultResult, long timeout)
    
{
        
this.result = defaultResult;
        
this.timeout = timeout;
        
this.setDaemon(true);  //标记为守护线程,不阻止程序退出
    }


    
public void run()
    
{
        
try {
            Thread.sleep(timeout);
            setResult(
null);
        }
 catch (InterruptedException e) {
            //e.printStackTrace();
        }

    }

    
    
//等待函数返回或超时
    public synchronized void waitFor()
    
{
        
while (!flag) {
            
try {
                wait();
            }
 catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }

    
    
public synchronized void setResult(Object o)
    
{
        
if (!flag) {
            
if (o != null) result = o;
            flag 
= true;
            notifyAll();
        }

    }

    
    
public Object getResult()
    
{
        
return result;
    }

}

 

示例:

public class Test3 
{
    
public long getResult1(int i, String s, long b)
    
{
        
try {
            Thread.sleep(
1500);
        }
 catch (InterruptedException e1) {
            //e1.printStackTrace();
        }

        
        
return i + b;
    }

    
    
public String getResult2(String s)
    
{
        
return "OK " + s;
    }

    
    
public void getResult3()
    
{
        
try {
            Thread.sleep(
100000);
        }
 catch (InterruptedException e) {
            //e.printStackTrace();
        }

    }

    
    
public static void main(String[] args)
    
{
        Worker worker 
= new Worker();
        Test3 test 
= new Test3();
        
        Object result 
= worker.work(
                
"getResult1"//函数名
                new Long(0), //超时返回值
                1000//超时时间
                test, //执行"getResult1"的对象
                new Object[]{new Integer(1), "dd"new Long(2)}//参数列表,基本数据类型需转为包装类对象,如int 1-->Integer(1)
                new int[]{02});  //基本数据类型的在参数列表中的索引,从0开始。如此处的int 1,long 2
        long r = ((Long)result).longValue();
        System.out.println(r);
        
        result 
= worker.work("getResult1"
                
new Long(0), 
                
3000
                test, 
                
new Object[]{new Integer(1), "dd"new Long(2)}
                
new int[]{0,2});
        r 
= ((Long)result).longValue();
        System.out.println(r); 
        
        result 
= worker.work("getResult2""default"3000, test, new Object[]{"HHH"}null);
        System.out.println(result);
        
        worker.work(
"getResult3"null1000, test, nullnull);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值