以Android环境为例的多线程学习笔记(四)----------Callable与Future

时间:2022-03-31 18:02:37

在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

的特性实现了在主线程和子线程的通信问题,在主线程中可以得到子线程的最后结果,和控制、判断子线程的运行状态,不过这种通信效果仅仅只是单向的,并不完美。

如果要实现线程间的完美通信,那就要用到一个更复杂的线程间的通信机制了,嗯,等下几次再详细的写这个线程通信问题吧。