Thread、Runnable、Callable、Future、FutureTask

Easter79
• 阅读 644

Thread、Runnable 实现的是void run()方法,Callable实现的是 V call()方法,并且可以返回执行结果,其中Runnable可以提交给Thread来包装下,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。

Future就是对于具体的调度任务的执行结果进行查看,最为关键的是Future可以检查对应的任务是否已经完成,也可以阻塞在get方法上一直等待任务返回结果。Runnable和Callable的差别就是Runnable是没有结果可以返回的.

FutureTask则是一个RunnableFuture,即实现了Runnbale又实现了Futrue这两个接口,另外它还可以包装Runnable和Callable,所以一般来讲是一个综合体了,它可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行,并且还可以通过v get()返回执行结果,在线程体没有执行完成的时候,主线程一直阻塞等待,执行完则直接返回结果。

package test;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * 测试Thread ,Runnable,Callable <br>
 * FutureTask 实现了RunnableFuture<V>,是个综合体。<br>
 * 以上所有多线程操作都会出现线程安全问题,需要特别处理。
 * 
 * @author Yuanqy
 *
 */
public class TestThread {

    public static void main(String[] args) {
        try {
            MyThread1 t1 = new MyThread1();// Thread
            MyThread2 t2 = new MyThread2();// Runnable
            MyThread3 t3 = new MyThread3();// Callable ==>Future
            MyThread3 tft = new MyThread3();// Callable ==>FutureTask

            ExecutorService es = Executors.newFixedThreadPool(100);
            for (int i = 0; i < 2; i++) {
                es.execute(t1);
                es.execute(t2);

                Future f1 = es.submit(t3);
                System.err.println("Future:" + f1.get());// get是阻塞的

                FutureTask ft = new FutureTask<Integer>(tft);// 使得Callable能用Runnable驱动
                es.execute(ft);
                System.err.println("FutureTask:" + ft.get());// get是阻塞的
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static class MyThread1 extends Thread {
        private int ticket = 0;

        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("[Thread]" + Thread.currentThread().getName() + ":" + (++ticket));
            }
        }
    }

    static class MyThread2 implements Runnable {
        private int ticket = 0;

        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("[Runnable]" + Thread.currentThread().getName() + ":" + (++ticket));
            }
        }
    }

    static class MyThread3 implements Callable<Integer> {
        private int ticket = 0;

        @Override
        public Integer call() throws Exception {
            for (int i = 0; i < 10; i++) {
                System.out.println("[Callable]" + Thread.currentThread().getName() + ":" + (++ticket));
            }
            return new Integer(ticket);// 有返回值
        }
    }
}
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
java多线程和异步回调
   在实际开发过程中遇到的多线程情况不多,但是在生产环境中多线程是最基本的情况,java面试时也会考到,所以看看多线程的知识还是很有必要的。 Thread,Runnable,Callable,Future,FutureTask,Executors这是java常见的接口和类。  thread.run():线程具体要执行的代码,thread.jo
灯灯灯灯 灯灯灯灯
3年前
阿里二面必备考题之Java并发!全面解析
一、使用线程有三种使用线程的方法:实现Runnable接口实现Callable接口继承Thread类实现Runnable和Callable接口的类只能当做一个可以在线程中运行的任务,不是真正意义上的线程,因此最后还需要通过Thread来调用。可以理解为任务是通过线程驱动从而执行的。实现Runnable接口cpublicclass
Wesley13 Wesley13
3年前
java多线程实现的三种方式
JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。1、继承Thread类实现多线程继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现
Stella981 Stella981
3年前
Executor线程池
线程池为线程生命周期的开销和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。_0_|_1_线程实现方式Thread、Runnable、Callable//实现Runnable接口的类将被Thread执行,表示一个基本任务p
Wesley13 Wesley13
3年前
Java面试系列
实现多线程的方式继承Thread类,重写run方法,调用start方法启动线程实现Runnable接口,重写run方法,调用start方法启动线程实现Callable接口,重写call方法,并用FutureTask包装,在newThread中传入FutureTask,然后调用start方
Wesley13 Wesley13
3年前
Java多线程(全)学习笔记(下)
七.Callable和Future接口    C可以把任意方法包装成线程执行体,包括那些有返回值的方法。Java也从jdk1.5开始,加入了Callable接口用来扩展Runnable接口的功能,Callable接口提供一个call()来增强Runnable的run()。因为call()可以有返回值,可以声明抛出
Wesley13 Wesley13
3年前
Java多线程之Callable和Future
本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果。 Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的
Wesley13 Wesley13
3年前
Java多线程之Callable、Future和FutureTask
我们学习java基础的时候,知道创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。而自从Java1.5开始,就提供了Callable和Future,通
Wesley13 Wesley13
3年前
Java多线程学习笔记
Java中创建多线程的三种方法1、继承Thread类创建线程2、实现Runnable接口创建线程3、使用Callable和Future创建线程\
Wesley13 Wesley13
3年前
Java并发编程:Callable、Future和FutureTask
在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。  这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。  如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。  而自从Java1.5开始,就提供了Callable和Future
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k