线程池

线程池引入

之前我们是需要一个线程就去创建一个线程,实现起来简单,但是当需要并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样由于频繁创建和销毁线程需要时间,就大大降低了系统的效率。

有没有一种办法可以使得线程复用,就是执行完一个任务,线程并不被销毁,而是可以继续执行其它任务呢?
有——线程池

线程池里面的每一个线程代码结束后,线程并不会死亡,而是成为线程池中的空闲线程

Executor、ExecutorService、Executors、ThreadPoolExecutor

Executor接口是一个顶层接口,在它里面只提供了一个方法:void execute(Runnable command)command为可运行的任务,就是用来执行传进去的任务的。

ExecutorService接口继承了Executor接口,并声明了一些方法:submit、invokeAll、invokeAny以及shutDown等;

Executors类提供了几个重要的方法:

newCachedThreadPool()
newFixedThreadPoll()
newSingleThreadExecutor()

newCachedThreadPool方法构建了一个线程池。对于每个任务,如果有空闲线程可用,立即让它执行任务,如果没有可用的空闲线程,则创建一个新线程。newFixedThreadPoll方法构建一个具有固定大小的线程池。如果提交的任务数多于空闲的线程数,那么把得不到服务的任务放置到队列中。当其他任务完成再运行它们。newSingleThreadExecutor是一个退化了的大小为1的线程池:由1个线程执行提交的额任务,一个接一个。这3个方法返回了ExecutorService接口的ThreadPoolExecutor类的对象。

ThreadPoolExecutor类继承了类AbstractExecutorService,实现了Executor、ExecutorService 接口。在ThreadPoolExecutor类中有几个非常重要的方法:

excute()
submit()
shutdown()
shutdownnow()
getQueue() 、getPoolSize() 、getActiveCount()、getCompletedTaskCount()等获取与线程池相关属性的方法

excute() 实际上是Executor中声明的方法,在ThreadPoolExecutor进行了具体的实现,这个方法是ThreadPoolExecutor的核心方法,通过这个方法可以向线程池提交一个任务,交由线程池去执行

submit()方法是在ExecutorService中声明的方法,在AbstractExecutorService就已经有了具体的实现,在ThreadPoolExecutor中并没有对其进行重写,这个方法也是用来向线程池提交任务的但是它和execute()方法不同,它能够返回任务执行的结果,去看submit()方法的实现,会发现它实际上还是调用的execute()方法,只不过它利用了Future来获取任务执行结果

shutdown()和shutdownNow()是用来关闭线程池的。调用了**shutdown()方法,则线程池处于SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕。调用了shutdownNow()**方法,则线程池处于STOP状态,此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务。

使用线程池

1.创建线程池对象:调用Excutors类中的静态方法newFixedThreadPool或者newCachedThreadPool方法;
2.给任务:调用submit方法提交任务(Runnable或Callable对象)
3.当不再提交任何任务时,调用shutdown。

使用Runnable还是Callable?
Callable是依赖于线程池存在的,不像Runnable可以依赖于线程(Thread类)和线程池,可见Callable的使用有一定局限性。Callable接口的call()方法有返回值,可以返回一个结果或抛出一个异常;Runnable接口的run()方法是void的,没有返回值。

代码:

//定义一个MyRunnable类实现Runnable接口
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for(int x=0; x<100;x++){
            System.out.println(Thread.currentThread().getName()+":"+x);
        }
    }
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolDemo {
    public static void main(String[] args){
       //创建一个具有固定大小(6)的线程池
        ExecutorService pool= Executors.newFixedThreadPool(6);

        //提交任务 可以执行Runnable或者Callable对象代表的线程
        pool.submit(new MyRunnable());
        pool.submit(new MyRunnable());
        pool.submit(new MyRunnable());
        pool.submit(new MyRunnable());
        pool.submit(new MyRunnable());
        pool.submit(new MyRunnable());

		//我不再提交任何任务了,所以结束线程池
        pool.shutdown();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值