对于批量任务进行处理,使用多线程
一.多线程的创建(使用)方式
1、继承Thread类创建多线程:
继承java.lang.Thread类,重写Thread类的run()方法,在run()方法中实现运行在线程上的代码,调用start()方法开启线程。
Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线程,并执行 run()方法。
2、实现Runable接口:
实现java.lang.Runnable接口,重写run()方法,在run()方法中实现运行在线程上的代码。
如果自己的类已经 extends 另一个类,就无法直接 extends Thread,此时,可以实现一个Runnable 接口。、
3、使用ExecutorService 、Callable<Class> 、Future 创建有返回值的线程
有返回值的任务必须实现 Callable 接口,类似的,无返回值的任务必须实现 Runnable 接口。执行Callable 任务后,可以获取一个 Future 的对象,在该对象上调用 get 就可以获取到 Callable 任务返回的 Object 了,再结合线程池接口 ExecutorService 就可以实现传说中有返回结果的多线程了。
二.线程的几种状态,以及它们之间是如何扭转的?
三.利用Executors创建的几种线程池
Java通过Executors提供四种线程池,分别为:
1. CachedThreadPool 可缓存线程池
1.由于corePoolSize为0所以任务会放入SynchronousQueue队列中,SynchronousQueue只能存放大小为1,所以会立刻新起线程。
2.核心线程数为0,最大线程总数为int最大值。
综上:如果创建的线程阻塞,新的task添加进来会不断创建线程,最终耗尽资源。
2.FixedThreadPool 定长线程池
1.工作队列为LinkedBlockingQueue,并且最大线程数和核心线程数设置相同的值,当corePoolSize满了之后就加入到LinkedBlockingQueue队列中。
2.每当某个线程执行完成之后就从LinkedBlockingQueue队列中取一个。
综上:可控制线程最大并发数,超出的线程会在队列中等待。
3. SingleThreadPool 单线程线程池
1.工作队列为LinkedBlockingQueue,最大线程数和核心线程数都为1。
2.它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
综上:具有缓冲队列的单线程的线程池。
4 .ScheduledThreadPool 按照固定频率执行的定长线程池。
1.继承了ThreadPoolExecutor。使用的阻塞队列时DelayQueue。
2.支持定时及周期性任务执行的线程池。