什么是线程?
他是操作系统中调度的最小单元,进程中可以包含多个线程
java中线程的实现方式有哪些?
1.继承Thread类:
建一个类并继承自Thread类,然后重写run()方法来定义线程要执行的任务。然后通过创建该 类的实例并调用start()方法来启动线程。
new Thread(){
@Override
public void run(){
System.out.println("@@@@主线程@@@"+Thread.currentThread().getId());
}
}.start();
2.实现Runnable接口:
你也可以实现Runnable接口,并实现其run()方法来定义线程要执行的任务。然后创建Thread 对 象,将实现了Runnable接口的对象作为参数传递给Thread的构造函数。
public class MyRunnable implements Runnable {
public void run() {
// 线程要执行的任务
}
}
// 启动线程
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
3.通过Callable和Future实现
通过Callable和Future可以实现并发编程,它们是Java并发包(java.util.concurrent)提供的 两个关键接口
(因为我们在使用Callble时要先创建一个线程池并提交任务,所以先给大家介绍一下线程池)
以下是线程池对象ThreadPoolExecutor(面试必问)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
//corePoolSize 核心线程数
//maximumPoolSize 最大线程数
//keepAliveTime 超过核心线程数的空闲线程的存活时间
//unit 时间单位
//workQueue 阻塞队列
//ThreadFactory 线程工厂
//Handler 拒绝策略
1.当一个任务通过submit或者execute方法提交到线程池的时候,如果当前池中线程数(包括闲置线程)小于coolPoolsize,则创建一个新的线程执行该任务;如果当前线程池中线程数已coolPoolSize,则将任务放入等待队列;
2.如果任务队列已满,则任务无法入队列,此时如果当前线程池中线程数小于maxPoolsize,则创建一个临时线程(非核心线程)执行该任务;如果当前池中线程数已经等于maxPoolSize,此时无法执行该任务,对于新的任务会根据拒绝执行策略处理;
注意事项:
当池中线程数大于coolPoolsize,超过keepAliveTime时间的闲置线程会被回收掉。回收的是非核心线程,核心线程一般是不会回收的。如果设置allowCoreThreadTimeOut(true),则核心线程在闲置keepAliveTime时间后也会被回收
4.通过线程池实现
拓展:
线程池有几种拒绝策略:
AbortPolicy(抛出异常中断程序执行)
这种拒绝策略在拒绝任务时,会直接抛出一个类型为
RejectedExecutionException 的RuntimeException,让你感知到任务被拒绝了,于是你便可以根据业务逻辑选择重试或者放弃提交等策略(默认)。
说白了不仅不处理当前任务,并且还抛出异常,中断当前任务的执行;
DiscardPolicy(任务丢弃不抛出异常)
当有新任务被提交后直接被丢弃掉,也不会给你任何的通知,相对而言存在一定的风险,因为我们提交的时候根本不知道这个任务会被丢弃,可能造成数据丢失。
o DiscardOldestPolicy(丢弃存活时长最长的任务)
丢弃任务队列中的头结点,通常是存活时间最长的任务,它也存在一定的数据丢失风险。
o CallerRunsPolicy(推荐)
第四种拒绝策略是,相对而言它就比较完善了,当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。
任务线程满了后,改策略可将执行的人为交换给主线程执行,这个过程相当于一个正反馈,此时如果主线程能处理,则处理,如果也不能处理,也就以为这当前服务不能接收新的任务了: