java调用方法超时设置_设置调用方法的超时时间

在工作中,遇到这样一个需求,我要做一个业务,要验证一下现有的数据是否正确,但这个验证又不是必须的,只是说如果这里验证不通过,后面流程就可以不走了,但是如果这里没有验证到,后面也会有验证。也就是说不影响主流程,算得上是一个优化吧。比如我要查询一个东西,但是这个时间不能超过1秒。

在网上查了一下,基本上都是异步执行,有两个线程来做。我查到有两种方法。

第一种 独立成一个类

代码如下:

(1)、FuncTimeOut类

///

///超时设置类///

public classFuncTimeOut

{///

///信号量///

private ManualResetEvent manu = new ManualResetEvent(false);///

///是否接受到信号///

private boolisgetSignal;///

///设置超时时间///

private inttimeout;///

///要委托调用的方法的一个委托///

private ActionfuncNeedRun;///

///构造函数///

/// 委托

/// 超时时间

public FuncTimeOut(Action action, inttimeout)

{this.funcNeedRun =action;this.timeout =timeout;

}///

///执行方法///

/// 参数

public void Execute(intparam)

{

Action tempAction = this.CombineActionAndManuset;var r = tempAction.BeginInvoke(param, this.MyAsynCallback, null);this.isgetSignal = this.manu.WaitOne(this.timeout);if (this.isgetSignal == true)

{

Console.WriteLine("未超时.");

Console.WriteLine("ThreadName:" +Thread.CurrentThread.Name);

}else{

Console.WriteLine("超时");

Console.WriteLine("ThreadName:" +Thread.CurrentThread.Name);

}

}///

///回调函数///

/// 异步操作时的状态

private voidMyAsynCallback(IAsyncResult ar)

{if (this.isgetSignal == false)

{

Console.WriteLine(Thread.CurrentThread.Name+ ",超时,放弃执行回调函数");

Thread.CurrentThread.Abort();

}else{

Console.WriteLine(Thread.CurrentThread.Name+ ",执行成功");

}

}///

///执行方法///

/// 参数

private void CombineActionAndManuset(intpara)

{

Thread.CurrentThread.Name= "subThread";this.funcNeedRun(para);this.manu.Set();

}

}

(2)、测试代码

///

///Class Program///

public classProgram

{///

///Defines the entry point of the application.///

/// The args.

public static void Main(string[] args)

{

TestFuncTimeOut();

Console.Read();

}#region FunTimeOut测试

///

///测试超时设置操作///

private static voidTestFuncTimeOut()

{

Console.WriteLine("start");

Thread.CurrentThread.Name= "Main";

FuncTimeOut ft= new FuncTimeOut(ComputeSum, 3000);

ft.Execute(10); // 测试修改点

Console.WriteLine("ThreadName:" +Thread.CurrentThread.Name);

Console.WriteLine("end");

}///

///Does the STH.///

/// The num.

private static void ComputeSum(intnum)

{int sum = 0;for (int i = 0; i < num; i++)

{

Thread.Sleep(500);

sum+=i;

Console.WriteLine(i+ ":ThreadName:" +Thread.CurrentThread.Name);

}

Console.WriteLine("sum =" +sum);//return sum;

}#endregion}

(3)、执行结果

a、超时的情况(上面的测试代码测出来的结果)

1 start2 0:ThreadName:subThread3 1:ThreadName:subThread4 2:ThreadName:subThread5 3:ThreadName:subThread6 4:ThreadName:subThread7 超时8 ThreadName:Main9 ThreadName:Main10 end11 5:ThreadName:subThread12 6:ThreadName:subThread13 7:ThreadName:subThread14 8:ThreadName:subThread15 9:ThreadName:subThread16 sum = 4517 subThread,超时,放弃执行回调函数

b、未超时的情况(将上述黄色部分的标示改为:ft.Execute(3);的结果)

1 start2 0:ThreadName:subThread3 1:ThreadName:subThread4 2:ThreadName:subThread5 sum = 36 未超时.7 ThreadName:Main8 ThreadName:Main9 end10 subThread,执行成功

(4)、总结

从上面的结果可以看出:

第一、有两个线程

第二、无论是否超时,方法都会被执行完毕,如果超时,则不忘下执行回调函数,否则执行。

第二种 封装成一个方法

(1)、源代码

///

///连续整数求和【测试方法】///

/// 个数

/// 结果

private static int ComputeSumResult(intnum)

{int sum = 0;for (int i = 0; i < num; i++)

{

Thread.Sleep(500);

sum+=i;

Console.WriteLine(i+ ",ThreadName:" +Thread.CurrentThread.Name);

}returnsum;

}///

///超时方法调用///

/// 要调用的方法

/// 要调用方法的参数

/// 超时时间

/// 结束

private static int CallWithTimeOutFun(Func func, int param, inttimeoutMillisecondes)

{

Thread threadToKill= null;int sum = 0;

Action wrappedAction= () =>{

threadToKill=Thread.CurrentThread;

threadToKill.Name= "threadToKill";

sum=func(param);

};

IAsyncResult result= wrappedAction.BeginInvoke(null, null);if(result.AsyncWaitHandle.WaitOne(timeoutMillisecondes))

{

Console.WriteLine("ThreadName:" +Thread.CurrentThread.Name);

wrappedAction.EndInvoke(result);

Console.WriteLine("没有超时");

Console.WriteLine("ThreadName:" +Thread.CurrentThread.Name);returnsum;

}else{

Console.WriteLine("ThreadName:" +Thread.CurrentThread.Name);

threadToKill.Abort();

Console.WriteLine("超时");

Console.WriteLine("ThreadName:" +Thread.CurrentThread.Name);returnsum;

}

}

(2)、测试代码

///

///Class Program///

public classProgram

{///

///Defines the entry point of the application.///

/// The args.

public static void Main(string[] args)

{

Console.WriteLine("start");

Thread.CurrentThread.Name= "Main";int result = CallWithTimeOutFun(ComputeSumResult, 10, 3000);// 测试需要修改的代码

Console.WriteLine("ThreadName:" + Thread.CurrentThread.Name + ", 结果是:" +result);

Console.WriteLine("end");

Console.Read();

}

}

(3)、测试结果

a、超时情况

1 start2 0,ThreadName:threadToKill3 1,ThreadName:threadToKill4 2,ThreadName:threadToKill5 3,ThreadName:threadToKill6 4,ThreadName:threadToKill7 ThreadName:Main8 超时9 ThreadName:Main10 ThreadName:Main, 结果是:0

11 end

b、不超时的情况(将上面测试需要修改的代码修改为:int result = CallWithTimeOutFun(ComputeSumResult, 3, 3000);// 测试需要修改的代码)

1 start2 0,ThreadName:threadToKill3 1,ThreadName:threadToKill4 2,ThreadName:threadToKill5 ThreadName:Main6 没有超时7 ThreadName:Main8 ThreadName:Main, 结果是:3

9 end

(4)、总结

从上面的结果可以看出:

第一、有两个线程

第二、如果方法超时,则不会将被调用的方法执行完毕,可以看出,方法是执行了,但由于超时,结果是不对的。如果方法没有超时,结果为正确的。这与上面方法的区别在于,方法超时就不会继续执行了。


版权声明:本文为weixin_31582099原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。