美文网首页
多线程创建的三种方式之实现Callable接口

多线程创建的三种方式之实现Callable接口

作者: 张轻舟 | 来源:发表于2019-06-21 21:02 被阅读0次

实现Callable接口创建线程
Callable接口是在jdk5版本中加入的,这个接口在java.util.concurrent包下面,与其他两种方式不同的地方在于使用Callable接口创建的线程会获得一个返回值并且可以声明异常。

使用Callable创建线程步骤:

1.自定义一个类实现java.util.concurrent包下的Callable接口
2.重写call方法
3.将要在线程中执行的代码编写在call方法中
4.创建ExecutorService线程池
5.将自定义类的对象放入线程池里面
6.获取线程的返回结果
7.关闭线程池,不再接收新的线程,未执行完的线程不会被关闭

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 多线程实现的第三种方法,实现Callable接口 优点: 可以获取返回值 可以抛出异常
 */

//1.定义一个类实现Callable<V>接口
class MyCallable implements Callable<Integer> {

    //睡眠时间
    private long second;

    //计算阶乘
    private int count;

    public MyCallable(int count, long second) {
        this.count = count;
        this.second = second;
    }

    // 2.重写call方法
    @Override
    public Integer call() throws Exception {
        // 3.将要执行的代码写在call方法中
        // 计算阶乘
        //让当前线程睡眠,单位是毫秒
        Thread.sleep(second);
        int sum = 1;

        if (count == 0) {
            sum = 0;
        } else {
            for (int i = 1; i <= count; i++) {
                sum *= i;
            }
        }

        // 打印线程名称
        System.out.println(Thread.currentThread().getName() + "-----sum=" + sum);

        return sum;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

}

public class ThreadTest03 {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //4.创建ExecutorService线程池
        ExecutorService exec = Executors.newCachedThreadPool();

        //5.创建存储Future对象的集合,用来存放ExecutorService的执行结果
        ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>();

        //6.开启2个线程,将返回的Future对象放入集合中
        for (int i = 0; i < 2; i++) {
            if (i == 0) {
                //计算5的阶乘,睡眠10秒
                results.add(exec.submit(new MyCallable(5, 10000)));
            } else {
                //计算3的阶乘,睡眠i秒
                results.add(exec.submit(new MyCallable(3, i)));
            }
        }


        for (Future<Integer> fs : results) {
            //7.判断线程是否执行结束,如果执行结束就将结果打印
            if (fs.isDone()) {
                System.out.println("计算结果:" + fs.get());
            } else {
                System.out.println(fs.toString() + "该线程还没有计算完毕,请耐心等待");
            }
        }

        //8.关闭线程池,不再接收新的线程,未执行完的线程不会被关闭
        exec.shutdown();
        System.out.println("main方法执行结束");
    }

}

线程池
线程池是初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时直接去这个线程集合中获取,而不是创建一个线程。任务执行结束后,线程回到池子中等待下一次的分配。

线程池的作用
解决创建单个线程耗费时间和资源的问题。

创建线程池
上面代码中演示了两种方式创建线程池

Executors.newFixedThreadPool(int nThreads);
通过传入的int类型参数来指定创建线程池中的线程数,如果任务数量大于线程数量,则任务会进行等待。
Executors.newCachedThreadPool();
会根据需要创建新线程的线程池,如果线程池中的线程数量小于任务数时,会创建新的线程,线程池中的线程最大数量是Integer.MAX_VALUE,int类型的最大值。如果线程的处理速度小于任务的提交速度时,会不断创建新的线程来执行任务,这样有可能会因为创建过多线程而耗尽CPU 和内存资源。

相关文章

  • java多线程

    多线程一共有三种创建方式 继承Thread类 实现Runable接口 实现Callable接口 1. Thread...

  • 二、线程的创建

    一、创建方式 线程的创建有三种方式: 继承Thread类 实现Runnable接口 实现Callable接口 注:...

  • 线程的创建-三种方式

    三种创建方式 一:继承Thread方式 二:实现Runnable接口 三:实现Callable接口实现 调用示例 ...

  • java并发基础

    创建线程的方式 创建线程主要有三种方法 : 继承Thread类,实现Runnable接口,实现Callable接口...

  • Java基础—多线程总结

    创建线程的三种方式 1.0 继承Thread类 2.0实现Runnable接口 3.0实现Callable接口 线...

  • java创建线程的方法

    java创建线程有三种方式,继承Thread类,实现Runnable接口,实现Callable接口;但Callab...

  • 线程创建的三种方式

    一、继承Thread 二、实现Runnable接口 三、实现Callable接口 创建线程的三种方式对比 并发工具...

  • code搬运工_深入多线程(v1)

    Runnable与Callable接口的方式创建多线程的特点 : 线程类只是实现了Runnable接口或Calla...

  • JDK5.0新增线程创建方式

    创建线程的方式三 实现Callable接口。 --- JDK 5.0新增 如何实现Callable接口 1.创建一...

  • Thread线程一览

    创建线程的三种方式: 继承Thread类 实现Runnable接口 实现了Callable接口(有返回值的线程) ...

网友评论

      本文标题:多线程创建的三种方式之实现Callable接口

      本文链接:https://www.haomeiwen.com/subject/yotpqctx.html