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

Java多线程入门4-实现Callable接口创建线程,第1张

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来启动我们新建的线程。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5686093.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存