线程创建的几种方式和线程池简述

tech2022-09-17  99

文章目录

前言一、初始化线程的几种方式?二、线程池创建的七大参数1.线程池各参数的含义2.线程的运行流程 总结


前言

本文是学习线程时的简要记录,仅供参考,如有纰漏,请大家指正。

一、初始化线程的几种方式?

1、继承Thread2、实现Runnable接口3、实现Callable接口+FutureTask(可以拿到返回结果,可以处理异常)4、创建线程池的方式。

方式1和方式2:主线程无法获取线程的运算结果。 方式3:主线程可以获取线程的运算结果,但是不利于控制服务器中的线程资源,可能导致服务器资源耗尽。 方式4:可以通过如下方式初始化线程池。 通过线程池初始化,性能稳定,也可以获取执行结果,并捕获异常。但是在业务复杂情况下,一个异步调用可能会依赖于另一个异步调用的执行结果。

Executors.newFixedThreadPool(10); //或者 new ThreadPoolExecutor( corePoolSize 5, maximumPoolSize 200, keepAliveTime 10, TimeUnit TimeUnit.SECONDS, BlockingQueue<Runnable> new LinkedBlockingQueue<>(10000), ThreadFactory Executors.defaultThreadFactory(), RejectedExecutionHandler new ThreadPoolExecutor.AbortPolicy() );

初始化线程示例代码如下:

public class ThreadTest { public static ExecutorService service = Executors.newFixedThreadPool(10); public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println("main....start"); //1、继承Thread Thread01 thread01 = new Thread01(); thread01.start(); //2、实现Runnable接口 Runnable01 runnable01 = new Runnable01(); new Thread(runnable01).start(); //3、实现Callable接口+FutureTask(可以拿到返回结果,可以处理异常) FutureTask<Integer> integerFutureTask = new FutureTask<>(new Callable01()); new Thread(integerFutureTask).start(); //等待整个线程执行结束,获取返回结果,阻塞等待 Integer integer = integerFutureTask.get(); //4、线程池 service.execute(new Runnable01()); //new ThreadPoolExecutor() ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 5, 200, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10000), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() ); System.out.println("main....end"); } //1、继承Thread public static class Thread01 extends Thread{ @Override public void run() { System.out.println("当前线程:"+Thread.currentThread().getId()); int i=10/2; System.out.println("运行结果:"+i); } } public static class Runnable01 implements Runnable{ @Override public void run() { System.out.println("当前线程:"+Thread.currentThread().getId()); int i=10/2; System.out.println("运行结果:"+i); } } public static class Callable01 implements Callable<Integer>{ @Override public Integer call() throws Exception { System.out.println("当前线程:"+Thread.currentThread().getId()); int i=10/2; System.out.println("运行结果:"+i); return i; } } }

二、线程池创建的七大参数

1.线程池各参数的含义

int corePoolSize:[5]核心线程数【5个一直存在除非设置了allowCoreThreadTimeOut】,线程池创建好以后就准备就绪的线程数量,就等待来接收异步任务去执行。

int maximumPoolSize:最大线程数量;控制资源并发的。

long keepAliveTime:存活时间,如果当前数量大于核心线程数量。线程空闲的时间大于存活时间,释放除核心线程外的超存活时间的空闲线程。

TimeUnit unit:时间单位。

BlockingQueue workQueue:阻塞队列,如果任务有很多,就会将目前多的任务放在队列里面。只要有空闲的线程,就会去队列中取出新的任务继续执行。

ThreadFactory threadFactory:线程的创建工厂,也可以自定义。

RejectedExecutionHandler handler:如果队列满了按照我们指定的拒绝策略拒绝执行任务。

2.线程的运行流程

1、线程池创建好,准备好core数量的核心线程,准备接收任务

1.1、core满了,就将再进来的任务放进阻塞队列中,空闲的core就会自己去阻塞队列获取任务执行1.2、阻塞队列满了,就直接开新线程执行,最大只能开到max指定的数量1.3、max满了就用RejectedExecutionHandler拒绝任务1.4、max都执行完了,在指定的时间keepAliveTime以后,释放,max-core数量的线程

2、线程池运行例题 假如一个线程池,corePoolSize:7,maximumPoolSize:20,workQueue:50,有100个线程同时进来,怎么分配?

先用7个直接可以得到执行,接下来50个进入阻塞队列排队,再多开13个线程继续执行。现在70个线程已经分配,剩下30个线程使用设置好的拒绝策略。

总结

本文为学习中的笔记,以后会继续完善。

最新回复(0)