栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java多线程入门4-实现Callable接口创建线程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java多线程入门4-实现Callable接口创建线程

  Callable接口类似于Runnable,但 Runnable不返回结果,也不能抛出被检查的异常。

一、JDK帮助手册

  打开JDK帮助手册,搜索Callable

  帮助手册告诉我们,Executors类包含实现方法,我们再搜索Executors

  JDK并未给出创建线程的示例,需要另外寻找资料列出详细创建过程。

二、创建过程与代码示例

  1、实现Callable接口,需要返回值类型;

  2、重写call方法,需要抛出异常;

  3、创建目标对象实例 t;

  4、创建执行服务:ExecutorService ser = Executor.newFixedThreadPool(1);

  5、提交执行:Future result = ser.submit(t);

  6、获取结果:boolean r = result.get();

  7、关闭服务:ser.shutdownNow();

  实现Callable接口创建线程:

public class ThreadDemo3 implements Callable {
    @Override
    public Boolean call() throws Exception {
        for(int i = 0; i < 10; i++) {
            // 休眠100毫秒,以免CPU执行太快,看不出实验结果
            Thread.sleep(100);
            // 获取当前线程名
            System.out.println(Thread.currentThread().getName() + ":计数" + i);
        }
        return true;
    }
}

  执行:

public static void main(String[] args) throws ExecutionException, InterruptedException {
    ThreadDemo3 t1 = new ThreadDemo3();
    ThreadDemo3 t2 = new ThreadDemo3();
    // 创建执行服务
    ExecutorService ser = Executors.newFixedThreadPool(2);
    // 提交执行
    Future result1 = ser.submit(t1);
    Future result2 = ser.submit(t2);
    //获取结果
    boolean r1 = result1.get();
    boolean r2 = result2.get();
    // 关闭服务
    ser.shutdownNow();
}

  输出:

  可以看到,两个线程交替执行。

三、使用

  在入门阶段,实现Callable接口创建线程了解即可。在实际工作中,都是基于线程池使用线程,也就是更多的是使用Callable接口的方式。

四、扩展
public
class Thread implements Runnable {
......
}

  我们知道,Thread类实现了Runnable接口。继承Thread类和实现Runnable接口的方式,都是基于Runnable接口创建线程。那么,Thread类并没有实现Callable接口,Callable接口又是如何创建线程的呢?

  1、先来看RunnableFuture接口的源码:

public interface RunnableFuture extends Runnable, Future {
    
    void run();
}

  RunnableFuture接口继承了Runnable接口和Future接口。

  2、Future接口实现类之一是FutureTask类,它的源码:

public class FutureTask implements RunnableFuture {
	......
    public FutureTask(Callable callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }    
}

  可以看到,FutureTask类的构造方法传入一个Callable类型的参数,然后赋值给它的私有属性。

  3、最后就是我们Thread类,无论我们以怎样的形式实现多线程,都需要调用Thread类中的start方法去向操作系统请求io,cup等资源,在Tread中有一个构造方法是传入一个Runnable接口类型的参数,而我们上面的FutureTask实例实现了 RunnableFuture 接口,而 RunnableFuture 接口又继承了Runnable接口和 Funture接口,因此我们可以将FutureTask 的一个实例当做是一个Runnable接口的实例传入Thread来启动我们新建的线程。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/685545.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号