Thread、Runnable、Callable、Future、FutureTask

Easter79
• 阅读 376

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
1年前
Java面试系列
实现多线程的方式继承Thread类,重写run方法,调用start方法启动线程实现Runnable接口,重写run方法,调用start方法启动线程实现Callable接口,重写call方法,并用FutureTask包装,在newThread中传入FutureTask,然后调用start方
Wesley13 Wesley13
1年前
Java编程思想笔记整理
实现线程的方法:(1)继承thread(底层实现了runable)(2)实现Runable(3)Executor创建线程池(4)实现Callable接口(带返回结果)对于callable接口,可以通过FutureTask包装实现线程,也可以使用ExecutorService对象的submit实现。使用executor创建线程
Wesley13 Wesley13
1年前
Java 四种线程池的用法分析
1、newThread的弊端执行一个异步任务你还只是如下newThread吗?newThread(newRunnable(){@Overridepublicvoidrun(){//TODOAutogeneratedm
Wesley13 Wesley13
1年前
Java基础教程——线程池
启动新线程,需要和操作系统进行交互,成本比较高。使用线程池可以提高性能——线程池会提前创建大量的空闲线程,随时待命执行线程任务。在执行完了一个任务之后,线程会回到空闲状态,等待执行下一个任务。(这个任务,就是Runnable的run()方法,或Callable的call()方法)。Java5之前需要手动实现线程池,Java5之
Wesley13 Wesley13
1年前
Java多线程之Callable和Future
本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果。 Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的
Wesley13 Wesley13
1年前
JAVA多线程实现的四种方式
Java(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Flib.csdn.net%2Fbase%2Fjavaee)多线程实现方式主要有四种:继承Thread类实现Runnable接口、实现Callable接口通过FutureTask包装
Wesley13 Wesley13
1年前
Java多线程学习笔记
Java中创建多线程的三种方法1、继承Thread类创建线程2、实现Runnable接口创建线程3、使用Callable和Future创建线程\
Wesley13 Wesley13
1年前
Java并发编程指南
  多线程是实现并发机制的一种有效手段。在Java中实现多线程有两种手段,一种是继承Thread类,另一种就是实现Runnable/Callable接口。  java.util.concurrent包是专为Java并发编程而设计的包。类图如下:!(https://oscimg.oschina.net/oscnet/29ddbb
Wesley13 Wesley13
1年前
java线程
1.进程和线程的区别是什么?进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫轻量级进程。2.创建线程有几种不同方式?你喜欢哪种?为什么?有三种方式可以用来创建线程:继承Thread类实现Runnable接口应用程序可以使用Executor框架来创建线程池实现Runnabl
Wesley13 Wesley13
1年前
java Future用法和意义一句话击破
在并发编程时,一般使用runnable,然后扔给线程池完事,这种情况下不需要线程的结果。 所以run的返回值是void类型。 如果是一个多线程协作程序,比如菲波拉切数列,1,1,2,3,5,8...使用多线程来计算。 但后者需要前者的结果,就需要用callable接口了。 callable用法和runnable一样,只不过调用的