dede视频网站模板,深圳做网站 信科便宜,河北地图,网页编辑代码线程池是一种多线程处理方式#xff0c;通过将任务添加到队列中#xff0c;在创建线程后自动启动这些任务。线程池中的线程可以复用#xff0c;可以控制最大并发数#xff0c;并且方便管理#xff0c;也就是说#xff0c;线程池会提前创建好一些线程#xff0c;当后续需… 线程池是一种多线程处理方式通过将任务添加到队列中在创建线程后自动启动这些任务。线程池中的线程可以复用可以控制最大并发数并且方便管理也就是说线程池会提前创建好一些线程当后续需要用到线程时从线程池里拿就行一旦任务结束线程并不会结束而是回归到线程池等待下一个任务然后继续执行。那么为什么不什么时候使用线程就什么时候创建线程呢这样不比往线程池里面拿线程更香吗这是错误的使用线程池显然更香因为使用线程池比从系统里面创建新的线程更快更高效。为什么呢因为如果是从系统这里直接创建线程需要调用系统api进一步的由操作系统内核完成线程的创建过程但是由于内核是为所有的线程服务的什么时候创建线程由系统内核决定如果在系统内核繁忙时创建则需要等待一定的时间使得内核有空闲时在创建因此它是不可控的而如果是从线程池这里获取线程上述的内核中进行的操作都是提前做好的就算系统繁忙也可以直接获取线程不需要等待因为它是直接创建好的现在取线程的过程纯粹的用户代码完成纯用户态它则是可控的。线程池有三种创建方式单一线程池、固定大小线程池和可伸缩线程池。单一线程池只有一个线程固定大小线程池指定了线程池的大小而可伸缩线程池可以根据需要动态改变线程池的大小。线程池的核心组成是线程和任务线程是前面学过的线程任务是实现了Runnable或Callable接口的实例对象。线程池的代码实现可以使用Executor框架中的Executors类来创建也可以使用ThreadPoolExecutor类来自定义线程池。
ExecutorService service Executors.newFixedThreadPool(4);//ExecutorService service是线程池的对象通过Executors里的方法来创建创建了有4个线程的线程池。
ExecutorService service1 Executors.newCachedThreadPool();//创建线程动态变化的线程池已经创建了的线程不会回收。
ExecutorService service2 Executors.newSingleThreadExecutor();//创建只有单个线程的线程池与直接创建线程相比更为方便。
线程池通过submit来添加任务参数为Runnable对象
service.submit(new Runnable() {Overridepublic void run() {System.out.println(haha);}
});
除此之外标准库还提供了一个接口更为丰富的线程池类ThreadPoolExecutor上述的线程池创建方法其实是对ThreadPoolExecutor的各个不同的创建方法而进行的封装。 ThreadPoolExecutor有多个构造方法但只需要掌握这一个就可以掌握所有的构造方法这一个构造方法就是
public ThreadPoolExecutor(int corePoolSize,//核心线程数int maximumPoolSize,//最大线程数long keepAliveTime,//线程最大空闲时间TimeUnit unit,//时间单位BlockingQueueRunnable workQueue,//管理任务的阻塞队列ThreadFactory threadFactory,//ThreadFactory threadFactory是线程工厂可以通过它来创建线程RejectedExecutionHandler handler)//拒绝方式
首先得知道ThreadPoolExecutor类的线程池里的线程个数并不是一成不变的而是会根据当前任务的情况动态发生变化但这样的变化也是有限制的corePoolSize和maximumPoolSize就是对里面线程数目的限制其中corePoolSize表示核心线程数也就是最少线程数而maximumPoolSize则表示最大线程数任你任务再多创建的线程数目也不能超过这个数目。当空闲的时候又会回收掉创建的线程但线程数目不能少于核心线程数这样就能保证繁忙时能高效的处理问题空闲时也不会浪费资源。long keepAliveTime和TimeUnit unit则表示允许线程空闲的时间其中keepAlive是时间数字如3000而unit则是单位如秒毫秒之类的当线程空闲时间超过这个时间后则会对该线程进行回收避免浪费资源。BlockingQueueRunnable workQueue则是要执行的任务线程池中有很多任务它们可以使用阻塞队列来进行管理这个阻塞队列既可以是线程池内置的也可以是手动指定的如根据优先级来指定一个优先级队列。ThreadFactory threadFactory是线程工厂可以通过它来创建线程可以通过不同ThreadFactory来来创建不同的线程。RejectedExecutionHandler handler是这里的重点它的含义是拒绝方式或者拒绝策略。当阻塞队列满了后继续添加任务该如何应对你或许会问让它在这里等待不就好了吗这样的方法可行但并不适合所有情况因此得需要一个确切的方式以下就是拒绝方式。
1)ThreadPoolExecutor.AbortPolicy当阻塞队列满了之后如果继续添加那么就会抛出异常线程池直接不干了不仅先前的任务不干了新添加的任务也不干了。
2ThreadPoolExecutor.CallerRunsPolicy谁是添加这个任务的线程谁去执行这个任务。
3ThreadPoolExecutor.DiscardOldestPolicy丢弃最早的任务执行新的任务。
4ThreadPoolExecutor.DiscardPolicy丢弃新的任务。