线程池的简单使用以及Callable接口

线程池的简单使用

概述:线程池就是一个池容器中有多个线程,当需要用到线程的时候,直接到线程池中去取一个线程拿来用就好了,当该线程用完后,该线程并没有被销毁,而是被归还到了线程池中,这样就减少了频繁的创建线程和销毁线程的操作,节约了资源的消耗。

java.util.concurrent->定义了关于线程池的接口

Executors类:
1.方法:static ExecutorService newFixedThreadPool(int nThreads) :获取线程池对象
参数:创建线程池对象的时候,指定线程池有多少个线程。
2.返回值: ExecutorService:才是真正的线程池对象
Future<?> submit(Runnable task):提交线程执行的任务->执行线程任务,执行run方法
Future<?>:接收设置线程任务方法的返回值的,由于重写的run方法无返回值,所以一般我不用写Future

void shutdown() :关闭线程池,一般我们不会去关闭线程池。

使用方式:

/**
创建一个线程类
*/
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"要执行了!");
    }
}

//测试类
public class ThreadPoolDemo {
    public static void main(String[] args) {
        //1.获取ExecutorService对象(获取线程对象,里面初始化有两个线程)
        ExecutorService es = Executors.newFixedThreadPool(2);
        //2.提交线程任务
        es.submit(new MyRunnable());
        es.submit(new MyRunnable());
        es.submit(new MyRunnable());
        //3.关闭线程池
        es.shutdown();
    }
}

因为目前线程池中只有两个线程,而我们调用了三个任务,它的执行流程是这样的:
在这里插入图片描述

Callable接口:类似于Runnable接口,都是一个设置线程任务的接口。
实现Callable接口之后要实现接口中的抽象方法 call() 类似于Runnable中的 run()
注意:call() 方法是有返回值的,它的返回值是一个 V (任意类型)

Future是一个接口,用于接收 submit() 返回的值,如果直接输出Future是一个地址值。
Future接口中的方法:
get() 获取Future中的内容

使用:

public class ExecutorsRandomDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //匿名内部类方式 定义一个生成随机数的线程范围1-0之间的随机数并返回
        Callable<Double> c = new Callable() {
            @Override
            public Double call() throws Exception {
                return Math.random();
            }
        };

        //创建线程池对象   池中线程有3个
        ExecutorService service = Executors.newFixedThreadPool(3);

        //调用Callable线程,会返回一个Future类型的数据
        Future<Double> f1 = service.submit(c);

        //get()获取线程返回的f1的内容 get方法有两个异常ExecutionException, InterruptedException 直接抛出去
        System.out.println(f1.get());

        //上述还可以链式调用
        Double d = service.submit(c).get();
        System.out.println(d);

        //关闭线程池
        service.shutdown();
    }
}


输出结果:
0.1273220550580514
0.4330091060101088

总结:如果线程无返回值的情况下我们可以使用 继承Thread类或实现Runnable接口 的方式
如果线程有返回值的情况下我们可以使用 实现Callable接口 的方式,并且使用Future接收,然后.get()方法获取Future中的内容。

发布了33 篇原创文章 · 获赞 35 · 访问量 1581

猜你喜欢

转载自blog.csdn.net/weixin_45216092/article/details/105090568