怎么给一个函数的运行设置超时

首先,为了使系统资源能更好分配,建立一个线程池:

		BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(3);  //Integer.MAX_VALUE
		ExecutorService mExecutor = new ThreadPoolExecutor(4, 6, 4, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.CallerRunsPolicy());

接着实现接口Callable的抽象方法call:

        Callable<Integer> callable = new Callable<Integer>() {  
            public Integer call() throws Exception {  
            	int result = reader.read();
              return result; 
            }  
        };

注意此call方法中的代码就是要对其实现超时机制的方法

然后把此callable对象作为构造参数,如下,产生一个FutureTask对象,因为FutureTask是Runnable的子类,所以可以把它提交给线程池来运行:

	        final FutureTask<Integer> future = new FutureTask<Integer>(callable); 
	        mExecutor.submit(future);//启动线程执行耗时操作
	        TimeOutRunnable timeOutRunnable = new TimeOutRunnable(0x3551,handler,1000 * 30,future);
	        mExecutor.submit(timeOutRunnable);//另启动一个线程来接收其返回值

与此同时,必须启动一个计时线程。后面两行就是启动一个计时线程来接收future对象的返回值,也就是耗时操作的返回值。计时线程具体实现如下:

package com.sodo.thread;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.sodo.util.LogUtils;

import android.os.Handler;

public class TimeOutRunnable implements Runnable {

	private String TAG = "TimeOutRunnable";
	private int msg;
	Handler handler;
	long outtime = 0L;
	Integer obj = -1;
	FutureTask<Integer> future = null;
	public TimeOutRunnable(int msg,Handler handler,long outtime,FutureTask<Integer> future) {
		this.msg = msg;
		this.handler = handler;
		this.outtime = outtime;
		this.future = future;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			if(future != null) {
				obj = future.get(outtime, TimeUnit.MILLISECONDS);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			obj = 2;
		} finally {
			if(handler != null) {
				handler.obtainMessage(msg, obj).sendToTarget();
			} else {
				LogUtils.e(TAG, "handler null");
			}
		}
		
	}

}

future.get(outtime,TimeUnit.MILLISECONDS)是一个阻塞方法,阻塞的时间是30秒,如果超过30秒future还没有返回,那么就会抛出TimeoutException。所以,UI就会根据此线程返回的obj值来显示相应的信息,如果obj等于2的话,代表的就是超时。


你可能感兴趣的:(怎么给一个函数的运行设置超时)