线程池——Runnable、Callable

线程池:顾名思义就是一个装了许多线程的池子

主要用来创建和管理线程对象的容器(达到线程复用的效果)

好处:

1.减少资源的消耗,避免频繁的创建和销毁线程

2.提高程序的响应速度

3.提高线程的可管理性

创建线程池对象,需要使用Executors工具类的方法

public static ExecutorService newFixedThreadPool(int nThreads)                  创建一个线程池对象,并规定池中包含nThreads个线程

ExecutorService es = Executors.newFixedThreadPool(5);

ExecutorService为线程池对象;参数 5 为线程的数量

 

线程池ExecutorService对象常用方法:

扫描二维码关注公众号,回复: 2784702 查看本文章

Future  <?>  submit​ (Runnable task)                          提交一个可运行的任务执行,并返回一个表示该任务Future对象

ExecutorService es = Executors.newFixedThreadPool(5);
Future<?> f = es.submit(new Runnable() {        //返回一个Future<?>对象
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
        }
    }
});
System.out.println(f);


Future <T>  submit  ​(Callable<T> task)                        提交值返回任务以执行,并返回代表任务待处理结果的Future

ExecutorService es = Executors.newFixedThreadPool(5);
Future<Integer> f = es.submit(new Callable<Integer>() {        //返回一个Future<T>对象
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 10; i++) {
            sum += i;
        }
        return sum;
    }
});

void shutdown()                                                                    销毁线程池

ExecutorService es = Executors.newFixedThreadPool(5);
es.shutdown();

使用完线程池后都应调用该方法销毁

线程池提交Runnable任务:

1.创建线程对象并制定线程数量

ExecutorService es = Executors.newFixedThreadPool(5);

2.创建实现Runnable接口的实现类,并重写Run方法

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
        }
    }
}

3.创建实现类对象,调用线程池submit()方法传递实现类对象

ExecutorService es = Executors.newFixedThreadPool(5);
es.submit(new MyRunnable());

4.销毁线程池

这样就完成了,从线程池中获取线程并执行Runnable任务

线程池提交Callable任务:

1.创建线程池并指定线程数量

ExecutorService es = Executors.newFixedThreadPool(5);

2.创建类实现Callable接口和重写call()方法

public class MyCallable implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 10; i++) {
            sum += i;
        }
        return sum;
    }
}

3.创建实现类对象,调用线程池的submit()方法,将实现类对象传入

ExecutorService es = Executors.newFixedThreadPool(5);
es.submit(new MyCallable());

4.销毁线程池

Future接口中有一个get()方法,可以获取Callable接口中,call方法的返回值

ExecutorService es = Executors.newFixedThreadPool(5);
Future<Integer> f = es.submit(new MyCallable());
System.out.println(f.get());            //输出:45

get还有阻塞的作用,会阻塞当前线程的执行

因为获取返回值一定要等待方法运行完才会有返回值

所以其他线程只能等该线程执行完或者使用线程池的其他线程

Callable和Runnable两种任务选择:

1.若执行任务完后,需要得到一个返回值,则使用Callable

2.若不需要返回值,则使用两种方法都可以

猜你喜欢

转载自blog.csdn.net/weixin_42022555/article/details/81661983