`

使用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可以判断线程是否执行完毕,已经通过它可以得到返回值。

分享到:
评论

相关推荐

    Java多线程之Callable接口的实现

    Java多线程之Callable接口的实现 Java中的多线程编程是指在一个程序中同时运行多个线程,以提高程序的执行效率和响应速度。在Java中,有两种方式可以实现多线程编程,即继承Thread类和实现Runnable接口。然而,在...

    Java多线程示例 可以直接运行

    本示例提供了可以直接运行的Java多线程代码,帮助开发者更好地理解和运用多线程。 一、继承Thread类 在Java中,可以通过创建一个新的类来继承Thread类,然后覆盖其run()方法,将需要并发执行的任务放入run()方法中...

    java通过线程控制程序执行超时(新)

    总结起来,Java通过线程控制程序执行超时是通过结合线程机制、Future/Callable接口以及中断机制实现的。在设计和实现超时控制时,要考虑到基本数据类型和反射的应用,以满足各种复杂的需求。合理地使用这些工具,...

    java单线程多线程clientserver

    此外,Java并发库(java.util.concurrent)提供了一些高级工具,如ExecutorService、Future、Callable等,帮助开发者更高效地管理多线程应用。 在客户端-服务器应用中,还需要考虑线程安全问题,确保在多线程环境下...

    java中的多线程实例详解(自己去运行看结果)

    线程状态转换是理解多线程的关键,包括新建、就绪、运行、阻塞和终止等状态。Java提供了一些线程控制方法,如`sleep()`使线程休眠,`join()`等待线程结束,`yield()`让当前线程暂停,以及`interrupt()`中断线程。 ...

    JAVA多线程教材

    7. **Future与Callable接口**:Future接口代表异步计算的结果,而Callable接口允许线程返回一个结果,与Runnable相比增加了返回值的能力,常与ExecutorService结合使用。 8. **线程安全与线程不安全**:理解哪些...

    Java多线程文档

    Java线程有五种状态:新建、就绪、运行、阻塞和死亡。线程的生命周期可以通过start()、run()、sleep()、join()、yield()、interrupt()等方法进行控制。 三、同步机制 1. synchronized关键字:用于方法或代码块,...

    java多线程实现大批量数据导入源码

    可以使用`ExecutorService`的`submit()`或`execute()`方法来执行任务,每个任务通常是一个实现了`Runnable`或`Callable`接口的对象。 在数据导入过程中,每个线程负责处理一部分数据,可能涉及到数据库连接的建立、...

    子线程任务发生异常,主线程事务如何回滚

    在 Java 中,我们可以使用 Callable 或 Runnable 接口来实现子线程的创建和执行。 其中,Callable 接口的 call 方法可以抛出异常,而 Runnable 接口的 run 方法不能抛出异常。因此,如果我们想捕获子线程的执行结果...

    JAVA集合、多线程

    5. **Future和Callable**:Callable接口允许返回结果,而Future接口则用于获取Callable的计算结果,这对于异步任务处理非常有用。 在实际开发中,我们需要根据具体需求选择合适的集合和多线程解决方案,以实现高效...

    java线程实例 各种小Demo

    3. 实现Callable接口与FutureTask:Callable接口的call()方法可以返回一个结果,FutureTask可以用于获取这个结果。这种方式适合需要返回值的多线程场景。 二、线程状态与控制 Java线程有五种状态:新建、可运行、...

    java多线程处理数据库数据

    然而,为了更好地管理和控制线程,Java并发包提供了如`ExecutorService`、`Future`、`Callable`等高级接口和类,它们简化了多线程编程,并提供了更好的资源管理。 在处理数据库数据时,我们通常会使用JDBC(Java ...

    java多线程,对多线程,线程池进行封装,方便使用

    7. **Future和Callable接口** 使用`Future`接口可以获取线程执行的结果,`Callable`接口则允许线程返回一个结果,它们与线程池结合使用可以实现异步计算。 8. **线程池的扩展** Java并发包中还有一些其他的...

    Java线程使用教程

    通过学习这个Java线程使用教程,你将能够熟练地在多线程环境中编写高效、安全的Java程序,理解线程同步、通信、线程池以及并发工具类的使用。阅读提供的"Java线程.pdf"和"说明.txt"文件将帮助你更深入地掌握这些知识...

    Java多线程程序设计

    Java线程有五种状态:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Terminated)。线程状态的转换由Java的线程API控制,如wait(), notify(), notifyAll()等。 三、线程同步 1. ...

    java学习资料-线程

    在Java中,线程的创建和管理是通过多种方式实现的,包括继承Thread类、实现Runnable接口以及实现Callable接口。 1. 继承Thread类 当你创建一个新的线程时,最直接的方法就是创建一个Thread类的子类,并覆盖run()...

    Java线程与多线程教程Java开发Java经验技巧共4页

    在Java中,线程是程序执行的基本单元,它允许程序同时执行多个任务,提高了程序的运行效率和响应速度。本教程将深入探讨Java线程与多线程的相关知识点,帮助开发者提升其编程能力。 1. **线程基础** - **线程的...

    Java多线程-JDK5.0新增线程创建方式

    #### 一、新增方式1:实现Callable接口 ##### (1)介绍 自Java 5.0起,为提高线程管理的灵活性与效率,引入了`Callable`接口,这是一种全新的创建线程的方式。与传统的`Runnable`接口相比,`Callable`接口具有...

Global site tag (gtag.js) - Google Analytics