java 并发——线程 (3)

上面说的创建和启动线程的本质几乎一样:new Thread(Runnable r).start() ,通过这种方式创建的线程称之为“野线程”,当线程体执行完之后线程就销毁了,再加上线程的创建,销毁和线程的调度,都是需要系统资源的开销。想象一下,在高并发场景下,不对线程数量加以控制,无限制创建线程,当达到系统性能的阈值,系统必然崩溃。所以创建野线程的这种方式实际项目中一般不用,而是使用线程池来管理线程。

线程池的优点:

可重用存在的线程,减少对象创建、消亡的开销,性能佳

可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞

提供定时执行、定期执行、单线程、并发数控制等功能

线程池框架

从网上扒来一张 java 线程池的框架图:

java 并发——线程

java 类库中,任务执行的主要抽象,不是 Thread, 而是 Executor , 看看 Executor 接口:

package java.util.concurrent; public interface Executor { void execute(java.lang.Runnable runnable); }

ExecutorService 接口继承了 Executor 接口,扩充了一些方法。线程池的核心实现类是 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor,前者用来执行被提交的任务,而ScheduledThreadPoolExecutor 可以在给定的延迟后运行任务,或者定期执行命令。

ThreadPoolExecutor 提供了四个构造方法:

public class ThreadPoolExecutor extends AbstractExecutorService { ..... public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler); ... }

参数最多的构造方法的参数说明:

corePoolSize:核心线程数。

maximumPoolSize:最大线程数。

keepAliveTime:线程存活时间。当线程数大于core数,那么超过该时间的线程将会被终结。

unit:keepAliveTime的单位。java.util.concurrent.TimeUnit类存在静态静态属性: NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS

workQueue:Runnable的阻塞队列。若线程池已经被占满,则该队列用于存放无法再放入线程池中的Runnable

threadFactory -执行创建新线程的工厂

handler -处理程序时因为达到线程边界和队列容量,使用的执行受阻

ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor ,同样有四个类似的构造方法,就不列举了。

Executors 是一个工厂类,提供了一些静态的方法操作线程池。通常创建线程池,我们不直接用调用 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 的构造方法,而是通过 Executors 类的五个静态工厂方法创建。

newFixedThreadPool(...) newSingleThreadExecutor(...) newCachedThreadPool(...) newScheduledThreadPool(...) newSingleThreadScheduledExecutor()



newSingleThreadExecutor
创建单线程的线程池 这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。
返回单线程的Executor,将多个任务交给此Exector时,这个线程处理完一个任务后接着处理下一个任务,若该线程出现异常,将会有一个新的线程来替代。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }

说明:LinkedBlockingQueue会无限的添加需要执行的Runnable。


newFixedThreadPool
创建一个包含指定数目线程的线程池,如果任务数量多于线程数目,那么没有执行的任务必须等待,直到有任务完成为止。每次提交一个任务就创建一个线程,直到线程达到线程池的最大小。任务线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjpws.html