在java语言中,可以通过new Thread的方法来创建一个新的线程执行任务,但是线程的创建是非常耗时的,而且创建出来的新的线程都是各自运行,缺乏统一的管理,这样做的后果可能是导致创建过多线程从而过度消耗系统资源,最终导致性能急剧下降,线程池的引入就是为了解决这个问题。
当使用线程池控制线程数量时,其他线程排队时,当一个任务执行完毕后再从队列中取最前面的任务开始执行。如果队列中没有其他线程排队,那么线程池中这一资源会处于等待状态,当一个新任务需要运行时,如果线程池中有等待工作线程,那么可以开始运行了,否则进入等待队列。
一方面,线程池中的线程可以被所有工作线程重复利用,一个线程可以用来执行多个任务,这样就减少了线程创建的次数,另一方面,他可以线程线程的个数,从而不会导致创建过多额线程而导致性能的下降。当需要执行任务的个数大于线程池中的个数,线程池会把这些任务放入到队列里,一旦任务运行结束,会有空闲线程,此时线程池就会从队列里取出任务继续执行。
目前java语言主要提供了4个线程池类:
1,newSingleThreadExecutor:创建一个单线程的线程池,它只会用唯一的工作线程来执行任务,也就是相当于单线程串行执行多有任务,如果这一唯一的线程以为异常结束,那么会有一个新的线程来代替它。
1 ExecutorService pool = Executors.newSingleThreadExecutor();
2 pool.execute(() => System.out.println(1));
3 pool.execute(() => System.out.println(2));
4 pool.execute(() => System.out.println(3));
5 pool.shutdown();
2,newFixedThreadPool:创建一个定长的线程池,可控制线程最大并发数,超出的线程会在队列中等待。使用这个线程池的时候,必须根据实际情况估算出线程的数量。
1 ExecutorService pool = Executors.newFixedThreadPool(2);
2 pool.execute(() => System.out.println(1));
3 pool.execute(() => System.out.println(2));
4 pool.execute(() => System.out.println(3));
5 pool.shutdown();
3,newCachedThreadPool:创建一个可缓存线程池,如果线程池的长度超过处理需要,那么可灵活回收空闲线程,如果不可回收,那么新建线程。此线程池不会对线程池的大小限制,线程池的大小完全依赖与操作系统或者说JVM能够创建的最大线程大小,使用这种方式需要在代码运行的过程中通过控制并发任务的数量来控制线程的数量。
1 ExecutorService pool = Executors.newCachedThreadPool();
2 pool.execute(() => System.out.println(1));
3 pool.execute(() => System.out.println(2));
4 pool.execute(() => System.out.println(3));
5 pool.shutdown();
4,newScheduledThreadPool:创建一个定长线程池,此线程池支持定时以及周期性执行任务的需求。
1 ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
2 pool.scheduleAtFixedRate(() => System.out.println(1), 0, 3000, TimeUnit.MILLISECONDS);
3 pool.scheduleAtFixedRate(() => System.out.println(2), 0, 3000, TimeUnit.MILLISECONDS);
4 pool.shutdown();