创建线程的方式
只有一种,就是 new Thread()!
即便是使用线程池,它也是这样的。
实现线程的方式
- 继承 Thread 类;
- 实现 Runnable接口,重写run方法【run方法无返回值】;
- 实现 Callable 接口,重写call方法【call方法有返回值】。
线程的生命周期
那顺便借一张图,简单复习一下操作系统层面线程的生命周期:
线程池几个参数的含义
- int corePoolSize:核心线程数,即便它们处于空闲状态也要保留在池中的线程数;
- int maximumPoolSize:池中允许的最大线程数
- long keepAliveTime:当线程数大于核心线程数时,这是多余的空闲线程将在终止之前等待新任务的最长时间;
- TimeUnit unit:keepAliveTime参数的时间单位;
- BlockingQueue<Runnable> workQueue:在执行任务之前用于保留任务的队列。 此队列将仅保存由 execute 方法提交的 Runnable 任务;
- ThreadFactory threadFactory:执行程序创建新线程时要使用的工厂;
- RejectedExecutionHandler handler:因达到线程边界和队列容量而被阻止执行时使用的处理程序;
四种拒绝策略
- AbortPolicy:抛出RejectedExecutionException异常;
- DiscardPolicy:不执行任何操作;
- DiscardOldestPolicy:丢弃最旧的未处理请求;
- CallerRunsPolicy:在调用者线程中执行任务。
线程池运行过程
- 当线程池中运行的线程数小于 coolPoolSize 时,每当来新的任务的时候,启动一个线程去执行当前的任务;
- 当线程池中运行的线程数大于等于 coolPoolSize 时,新来的任务将进入阻塞队列等待被执行;
- 当阻塞队列中任务满了的时候,将使用 maximumPoolSize 设置的值,即启动额外的线程来执行新来的任务;
- 当线程池中运行的线程数大于等于 maximumPoolSize 时,启动拒绝策略来拒绝后续的任务。
上面只是一个大致的执行流程,详细的流程比上面要复杂的多,具体可以查阅 execute(Runnable command)
方法和 addWorker(Runnable firstTask, boolean core)
方法的源码!
好了,多线程的大纲差不多就这些吧!继续加油!!!