在JAVA的多线程机制中,Runnable接口可以用来封装一个异步运行的任务,但是它相当于是一个没有参数类型和返回
值的异步方法,所以在JAVA中就又出现了callable机制,callable是一个参数化的类型接口,里面只有一个call方法,但是该方法是
有返回值的,而且返回值类型就是参数类型。与callable接口相配套使用的就是Future接口,其作用就是用来保存异步运算的结果和
和启动一个异步运算,Future接口中一共有五个方法,分别用来查询和控制线程运行的状态和结构。
Future接口中的方法列表:
public interface Future<V> { V get() throws ....;//用来返回运算的最后结果,如果计算还未完成,则会被阻塞 /* *如果计算完成,则返回true *如果计算完成之前,调用这个方法超时,则会发生TimeoutException异常。 *如果运行时线程被中断则会发生InterruptedException中断异常 *否则被阻塞 */ V get(long timeout,TimeUnit unit) throws...; /* * 取消运算,mayInterrupt为true时中断线程,但此时如果线程已经被阻塞或者休眠则会发生InterruptedException中断异常 */ void cancle(boolean mayInterrupt); boolean isCancleed();//判断线程是否被取消 boolean isDone();//判断计算是否已经完成 }
但是在实际的运用中间我们还有更简洁的机制那就是FutureTask包装器,它可将Callable转换成Future和Runnable,它同时是实现了两者的接口的。
具体的使用方法如下面的代码:
/** * 定义一个任务类,实现Callable接口 */ public static class MyCallableClass implements Callable<String>{ private int value = 0; public MyCallableClass(int flag){ this.value = flag; } public String call() throws Exception{ if (this.value == 0){ // 如果value的值为0,则立即返回 return "value = 0"; } } else { // value不为0,则抛出异常 throw new Exception("Invalid value!"); } } }
//开启线程
case R.id.button3: MyCallableClass task1 = new MyCallableClass(0); FutureTask<String> Futask = new FutureTask<String>(task1); Thread t = new Thread(Futask); t.start(); try{ System.out.println("task1: " + Futask.get()); } catch(Exception e) { System.out.println(e.toString()); } break;
线程结束后,最后的结果将会输出“alue=0”。这样也就简单的实现了将一个线程里运算结果最后返回的效果,其实这个功能说更简单一点也就是利用Future
的特性实现了在主线程和子线程的通信问题,在主线程中可以得到子线程的最后结果,和控制、判断子线程的运行状态,不过这种通信效果仅仅只是单向的,并不完美。
如果要实现线程间的完美通信,那就要用到一个更复杂的线程间的通信机制了,嗯,等下几次再详细的写这个线程通信问题吧。