线程、线程等待、线程定时器、线程池的使用
最近项目使用到多线程相关的技术,重新温习了下总结下
一、创建线程的方法:
1、继承THread类
2、实现Runable接口创建线程
相较于第一种方式,这种实现方式多出了start、stop、sleep方法
3、实现callable使用future可以实现
相较于前两种方式,这种实现方式线程可以有结果
二、线程等待
1、Thread.sleep()
缺点:算时间,如果想让主程序在所有线程后执行,需要手动计算主程序的等待时间要大于所有程序等待时间
class MyTheads1 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" test"+Thread.currentThread().getName());
}
}
class MyTheads2 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" test"+Thread.currentThread().getName());
}
}
public static void main(String[] args) throws InterruptedException {
MyThead1 myThead1=new MyThead1();
MyThead2 myThead2=new MyThead2();
// myThead1.start();
// myThead2.start();
// 等待时间设置为大于所有线程等待时间才能实现主程序在所有线程结束后执行
Thread.sleep(2500);
System.out.println(Thread.currentThread().getName()+"main");
}
}
打印结果:
Thread-2 testThread-2
Thread-1 testThread-1
mainmain
2、Thread jion()
等待线程执行完成主程序再执行
执行结果如下
三、异步定时器 TimerTask()
四、线程池
1、线程池介绍
线程池的最上层接口是Executor,这个接口定义了一个核心方法execute(Runnabel command),这个方法最后被ThreadPoolExecutor类实现,这个方法是用来传入任务的。而且ThreadPoolExecutor是线程池的核心类。
corePoolSize:核心线程池的大小,如果核心线程池有空闲位置,这是新的任务就会被核心线程池新建一个线程执行,执行完毕后不会销毁线程,线程会进入缓存队列等待再次被运行。
maximunPoolSize:线程池能创建最大的线程数量。如果核心线程池和缓存队列都已经满了,新的任务进来就会创建新的线程来执行。但是数量不能超过maximunPoolSize,否侧会采取拒绝接受任务策略,我们下面会具体分析。
keepAliveTime:非核心线程能够空闲的最长时间,超过时间,线程终止。这个参数默认只有在线程数量超过核心线程池大小时才会起作用。只要线程数量不超过核心线程大小,就不会起作用。
unit:时间单位,和keepAliveTime配合使用。
workQueue:缓存队列,用来存放等待被执行的任务。
threadFactory:线程工厂,用来创建线程,一般有三种选择策略。如下:
ArrayBlockingQueue; LinkedBlockingQueue; SynchronousQueue;
handler:拒绝处理策略,线程数量大于最大线程数就会采用拒绝处理策略,四种策略为:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程) ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
Executor接口有一个子接口ExecutorService,ExecutorService的实现类为AbstracExecutorService,而ThreadPoolExcutor正是AbstrcExecutorService的子类。
ThreadPoolExecutor还有两个常用的方法shutdown和submit,两者都用来关闭线程池,但是后者有一个结果返回。
2、线程池springboot中的应用
创建线程池
添加线程池配置属性类