创建线程的第三种方式——使用Callable接口

Callable是类似于Runnable的接口,实现Callable的类和实现Runnable的类都是可被其他线程执行的任务。

优点:有返回值

缺点:实现繁琐

简单实现:

CallableAndFuture.java
/**
 * 简单实现
 *
 * @author :liuqi
 * @date :2018-06-13 11:10.
 */
public class CallableAndFuture {
    static class MyThread implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "Hello world";
        }
    }

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        Future<String> future = threadPool.submit(new MyThread());
        try {
            System.out.println(future.get());
        } catch (Exception e) {

        } finally {
            threadPool.shutdown();
        }
    }
}

运行结果:

Hello world

进阶:

Race.java
/**
 * 实现callable类
 *
 * @author :liuqi
 * @date :2018-06-13 10:13.
 */
public class Race implements Callable<Integer> {
    private String name;
    private long time;
    private boolean flag = true;
    // 步数
    private int step = 0;
    public Race(){
    }
    public Race(String name,int time){
        super();
        this.name = name;
        this.time = time;
    }
    @Override
    public Integer call() throws Exception {
        while(flag){
            Thread.sleep(time);
            step++;
        }
        return step;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public int getStep() {
        return step;
    }

    public void setStep(int step) {
        this.step = step;
    }
}
Demo05.java
/**
 * 使用collable接口创建线程
 *
 * @author :liuqi
 * @date :2018-06-13 10:22.
 */
public class Demo05 {
    public static void main(String[] args) throws InterruptedException,ExecutionException {
        // 创建两个线程
        ExecutorService ser = Executors.newFixedThreadPool(2);
        Race tortoise = new Race("乌龟",1000);
        Race rabbit = new Race("兔子",500);
        // 获取future对象
        Future<Integer> result1 = ser.submit(tortoise);
        Future<Integer> result2 = ser.submit(rabbit);
        // 2秒
        Thread.sleep(2000);
        // 停止线程体循环
        tortoise.setFlag(false);
        rabbit.setFlag(false);
        // 获取值
        int num1 = result1.get();
        int num2 = result2.get();
        System.out.println("乌龟跑了 " + num1 + "步");
        System.out.println("兔子跑了 " + num2 + "步");
        // 停止服务
        ser.shutdownNow();
    }
}

运行结果:

乌龟跑了 3步
兔子跑了 5步

代码地址:https://github.com/yuki9467/TST-javademo/tree/master/src/main/thread

Callable和Runnable有几点不同:

1.Callable规定方法是call(),而Runnable规定方法是run();

2.Callable任务执行后可返回值,而Runnable不能返回值;

3.call()可抛出异常,而run()不能抛出异常;

4.运行Callable任务可拿到一个Future对象,Future表示异步计算的结果,通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。

原文地址:https://www.cnblogs.com/yuki67/p/9176909.html

时间: 2024-11-05 15:55:47

创建线程的第三种方式——使用Callable接口的相关文章

JDBC 创建连接对象的三种方式

创建连接对象的三种方式 //第一种方式 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?user=root&password=root") ; //第二种方式 //读取properties文件 Properties pro = new Properties() ; InputStream in = JdbcDemo3.class.getClassLoader().ge

Java反射机制(创建Class对象的三种方式)

1:SUN提供的反射机制的类: java.lang.Class<T> java.lang.reflect.Constructor<T> java.lang.reflect.Field java.lang.reflect.Method java.lang.reflect.Modifier 2:什么是反射 JAVA反射机制是在运行状态中,对于任意一个类.都能都知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称

spring中创建bean对象的三种方式以及作用范围

时间:2020/02/02 一.在spring的xml配置文件中创建bean对象的三种方式: 1.使用默认构造函数创建.在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数函数,则对象无法创建. <bean id="one" class="sdnu.machi.one"></bean> 如果one.class中没有默认构造函数则会报

IOS 多线程,线程同步的三种方式

一般情况下我们使用线程,在多个线程共同访问同一块资源.为保护线程资源的安全和线程访问的正确性. 在IOS中我们一般情况下使用以下三种线程同步代码方式: 第一种和第二种代码同步的使用方法,一般情况下我们只需要使用NSLock和NSCondition申明2个属性.然后给此属性赋对应的值.那么即可作为安全防控的线程手段. 同时也可以保证线程的资源安全. 1:NSLock方式 [xxxlock   lock] //上锁 同步代码块 [xxxlock   unlock]//解锁 2:NSCondition

Java中创建线程用第几种方式

2015年11月19日10:16:33 作者:数据分析玩家 //用第一种方法创建线程:每个线程处理的是不同的资源//每个线程分别对应20张电影票,之间并无任何关系,这就说明每个线程之间是平等的,没有优先级关系class Tc extends Thread { private int tickets = 20;//每个线程各自卖20张票 public String name ; public Tc(String name) { this.name = name; } public void run

线程实现的三种方式

第一种:继承Thread类,重写 Thread 类的 run 方法. class ThreadDemo extends Thread{ @Override public void run() { // TODO Auto-generated method stub super.run(); } } ThreadDemo td=new ThreadDemo(); td.start(); 第二种:实现Runnable接口,然后实现 run 方法.在创建 Thread 时作为一个参数来传递并启动. c

[Andriod]计时器实现-基于线程消息机制三种方式

在Android开发中,定时器一般有以下3种实现方法: 一.采用Handler与线程的sleep(long)方法二.采用Handler的postDelayed(Runnable, long)方法三.采用Handler与timer及TimerTask结合的方法 下面逐一介绍: 一.采用Handle与线程的sleep(long)方法 Handler主要用来处理接受到的消息.这只是最主要的方法,当然Handler里还有其他的方法供实现,有兴趣的可以去查API,这里不过多解释. 1. 定义一个Handl

创建spring boot的三种方式

一. 在线创建 1.在线的地址:https://start.spring.io/ 然后填写你自己需要的版本最后 点击Generate the project 按钮下载 最后引用就可以了 二.使用IDE创建 我使用的工作工具是IDEA 接下来是要注意一下  你选择的路径地址当你修改project location时后面要自己手动添加 工程名字 然后点击完成 就可以了. 三.通过maven来构建 由于spring boot ,本质上是一个maven工程,因此可以先创建maven工程,再次改造成一个s

React创建组件的三种方式及区别

React创建组件具体的三种方式: 1.函数式定义的无状态组件 2.es5原生方式React.createClass定义的组件 3.es6形式的extends React.Component定义的组件 虽然有三种方式可以定义React组件,但是它们有什么不同呢?什么情况下应该使用哪种定义方式呢?请继续往下看 接下来我们先说一下三种方式有什么区别? 1.无状态函数式组件 它是为了创建纯展示组件,这种组件只负责根据传入的props来展示,不涉及到要state状态的操作. 无状态函数式组件形式上表现为