`

使用Java的Callable接口运行线程

    博客分类:
  • Java
阅读更多

Runnable和Callable的区别:
(1)Runnable是自从java1.1就有了,而Callable是1.5之后才加上去的
(2)Callable规定的方法是call(),Runnable规定的方法是run()
(3)Callable的任务执行后可返回值,而Runnable的任务是不能返回值(是void)
(4)call方法可以抛出异常,run方法不可以
(5)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索
计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
(6)加入线程池运行,Runnable使用ExecutorService的execute方法,Callable使用submit方法。

Callable接口也是位于java.util.concurrent包中。Callable接口的定义为:

 

public interface Callable<V>   
{   
    V call() throws Exception;   
} 

 

 测试使用代码,定义一个实现Callable接口的类OneTask:

 

import java.util.concurrent.Callable;

public class OneTask implements Callable<String> {//callable有个<V>,这个V就是call函数的返回值类型
	private int id;
	public OneTask(int id){
		this.id = id;
	}
	@Override
	public String call() throws Exception {//这儿可以抛出异常,而Runnable接口的run函数不可以
		int i=5;
		while (i>=0) {
			System.out.println("Thread "+ id +" is working");
			Thread.sleep(1000);
			i--;
		}
		return "result of Test2 " + id; //Runnable接口的run函数是没有返回值的
	} 
}

 执行Callable的线程的方法可以借助FutureTask或者加入到线程池中。首先看怎么用FutureTash执行,代码如下:

 

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
 
public class Test1 { 
	 
	public static void main(String[] args) {
		Callable<String> oneCallable = new OneTask(1);
		FutureTask<String> ft= new FutureTask<String>(oneCallable);
		//FutureTask<String>是一个包装器,它通过接受Callable<String>来创建,它同时实现了Future和Runnable接口
		
		new Thread(ft).start();
    
        while(!ft.isDone()){
            try {
                System.out.println("检查线程执行完了吗...");
                Thread.sleep(1000);
            } catch (InterruptedException e) { 
                e.printStackTrace();
            }
        }
        
        String result = "";
        try {
        	result = ft.get();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(result);
	}
}

 

 参考http://www.cnblogs.com/yjl49/archive/2012/09/26/2704274.html,FutureTash扮演监督的角色,主线程通过不断询问实现Callable的类对应的线程是否执行完毕,最后可以得到返回的结果。通过线程池的方式如下:

 

import java.util.ArrayList; 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Test3 {

	public static void main(String[] args){
		// TODO Auto-generated method stub
		ExecutorService exec = Executors.newCachedThreadPool();  
        ArrayList<Future<String>> results = new ArrayList<Future<String>>();    
        //Future 相当于是用来存放Executor执行的结果的一种容器  
        
        for (int i = 0; i < 10; i++) {  
            results.add(exec.submit(new OneTask(i)));  
        }  
        
        for (Future<String> fs : results) {  
            if (fs.isDone()) {  
            	try {
            		System.out.println(fs.get()); 
				} catch (Exception e) {
					e.printStackTrace();
				}
            } else {  
                System.out.println("Future result is not yet complete");  
            }  
        }  
        exec.shutdown();    
	}
}

 线程池的submit方法会返回一个Future,通过这个Future可以判断线程是否执行完毕,已经通过它可以得到返回值。

分享到:
评论

相关推荐

    多线程机制

    多线程机制 1 1、 Runnable接口与Thread类 1 2、 两个创建线程方法的比较 3 3、 几个常用的改变线程状态的方法 3 4、 线程的同步机制 8 ...10、 Callable结合FutureTask的多线程使用(免打扰模式) 24

    深入理解高并发编程-Java线程池核心技术

    java并发编程实战pdf 线程与多线程 1.线程 在操作系统中,线程是比进程更小的能够独立运行的基本单位。同时,它也是 CPU 调度的基本单位。...Runnable 接口,实现 Callable 接口。简单的示例代码分别如下所示。

    Java多线程详解

    文章目录1、进程与线程2、创建多线程2.1、继承Thread类2.2、实现Runnable接口2.3、使用匿名内部类实现2.4、实现Runnable接口的好处2.5、使用Callable和Future创建线程3、线程的生命周期4、几种特殊线程4.1、join线程...

    jdk 1.5 线程的使用,简单例子

    通过接口java.util.concurrent.Callable 的使用 实现线程的启用,程序为一个main的例子,可以直接运行(jdk1.5 以上版本)

    疯狂JAVA讲义

    学生提问:当我们使用编译C程序时,不仅需要指定存放目标文件的位置,也需要指定目标文件的文件名,这里使用javac编译Java程序时怎么不需要指定目标文件的文件名呢? 13 1.5.3 运行Java程序 14 1.5.4 根据...

    Java并发编程(学习笔记).xmind

    (2)建模简单:通过使用线程可以讲复杂并且异步的工作流进一步分解成一组简单并且同步的工作流,每个工作流在一个单独的线程中运行,并在特定的同步位置交互 (3)简化异步事件的处理:服务器应用程序在接受...

    \java超强笔记(超级经典)

    Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。Callable和Runnable有几点不同: Callable规定的方法是call(),而Runnable规定的方法是run(). ...

    java面试题.docx

    企业常见java面试题,java基础,java进阶 JDK 和 JRE 有什么区别? == 和 equals 的区别是什么? 两个对象的 hashCode()相同,则 equals()也一定为 true,... 在 java 程序中怎么保证多线程的运行安全? 什么是死锁?

    JAVA多线程精讲下

    通过本门课程的学习你可以深刻理解Java多线程的原理及实现运行机制,深刻学习多线程的生命周期、调度、控制等内容。 多线程精讲下课程内容涵盖如下:l 线程的同步(线程安全问题)l 线程的死锁l 线程间通信l ...

    Java2核心技术.part5

    2.5使用文本编辑器编译并运行程序 2.6运行图形化应用程序 2.7建立并运行applet 第3章Java基本的程序设计结构 3.1一个简单的Java应用程序 3.2注释 3.3数据类型 3.3.1整型 3.3.2浮点型 3.3.3 ...

    Java常见面试题208道.docx

    47.在 java 程序中怎么保证多线程的运行安全? 48.多线程锁的升级原理是什么? 49.什么是死锁? 50.怎么防止死锁? 51.ThreadLocal 是什么?有哪些使用场景? 52.说一下 synchronized 底层实现原理? 53....

    corejava培训文档

    1. 前言 1.1. JAVA特点 1.2. 运行原理 1.3. JAVA目录 2. 一 基础知识 2.1. 配置环境 2.2. Java中基本概念 3. 二 定义,关键字和类型 3.1. 注释的三种形式 3.2. Java代码中的“;...17.10. Callable 和 Future接口

    Java2核心技术.part3

    2.5使用文本编辑器编译并运行程序 2.6运行图形化应用程序 2.7建立并运行applet 第3章Java基本的程序设计结构 3.1一个简单的Java应用程序 3.2注释 3.3数据类型 3.3.1整型 3.3.2浮点型 3.3.3 ...

    Java2核心技术.part1

    2.5使用文本编辑器编译并运行程序 2.6运行图形化应用程序 2.7建立并运行applet 第3章Java基本的程序设计结构 3.1一个简单的Java应用程序 3.2注释 3.3数据类型 3.3.1整型 3.3.2浮点型 3.3.3 char类型 ...

    Java2核心技术.part6

    2.5使用文本编辑器编译并运行程序 2.6运行图形化应用程序 2.7建立并运行applet 第3章Java基本的程序设计结构 3.1一个简单的Java应用程序 3.2注释 3.3数据类型 3.3.1整型 3.3.2浮点型 3.3.3 ...

    Java2核心技术.part4

    2.5使用文本编辑器编译并运行程序 2.6运行图形化应用程序 2.7建立并运行applet 第3章Java基本的程序设计结构 3.1一个简单的Java应用程序 3.2注释 3.3数据类型 3.3.1整型 3.3.2浮点型 3.3.3 ...

    Java2核心技术.part2

    2.5使用文本编辑器编译并运行程序 2.6运行图形化应用程序 2.7建立并运行applet 第3章Java基本的程序设计结构 3.1一个简单的Java应用程序 3.2注释 3.3数据类型 3.3.1整型 3.3.2浮点型 3.3.3 ...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【多线程】Callable 和 Runnable接口 82 【多线程】Java四种线程池的创建方法 83 【多线程】线程池原理和运行机制 83 【多线程】线程池对任务的处理 85 【多线程】线程池的状态 86 线程池的状态说明 86 各个状态之间...

Global site tag (gtag.js) - Google Analytics