java线程
并行:同时进行操作
并发:多线程进行,但由cpu确定不同时间段哪个线程的继续执行。
- 多线程
1.1 多线程创建方式:继承Thread,实现Runnable,实现Callable
① 继承Thread,重写run方法
② 实现Runnable,重写run方法,使用Thread类进行包装
③ 实现Callable,重写call方法,使用FutureTask包装,包装成Thread
三者的比较:
Thread: 继承方式, 不建议使用, 因为Java是单继承的,继承了Thread就没办法继承其它类了,不够灵活
Runnable: 实现接口,比Thread类更加灵活,没有单继承的限制
Callable: Thread和Runnable都是重写的run()方法并且没有返回值,Callable是重写的call()方法并且有返回值并可以借助FutureTask类来判断线程是否已经执行完毕或者取消线程执行
当线程不需要返回值时使用Runnable,需要返回值时就使用Callable,一般情况下不直接把线程体代码放到Thread类中,一般通过Thread类来启动线程
Thread类是实现Runnable,Callable封装成FutureTask,FutureTask实现RunnableFuture,RunnableFuture继承Runnable,所以Callable也算是一种Runnable,所以三种实现方式本质上都是Runnable实现
1.2 线程的状态:创建状态(new对象),就绪状态(start后,),运行状态(获得cpu的时间片段),阻塞状态(线程挂起,时间片段结束),死亡状态(run结束,发生异常),锁池状态(寻找锁,释放cpu时间片段,找到就返回就绪状态,)
1.3 获得当前的线程:Thread.currentThread()
1.4 start和run方法:start是将线程进入就绪状态,run是线程运行状态运行的代码
1.5 sleep() 与 interrupt():sleep将进程进入阻塞状态,并释放时间片段,但不会进行释放锁,sleep结束后,将携带返回就绪状态;interrupt(): 唤醒正在睡眠的程序,调用interrupt()方法,会使得sleep()方法抛出InterruptedException异常,当sleep()方法抛出异常就中断了sleep的方法,从而让程序继续运行下去
1.6 wait() 与 notify()notifyall:全部是object的final修饰的方法,不能进行重写。Wait让进程进入阻塞状态,并且释放锁,一直等到被其他线程notify或者notifyall唤醒,如果当前线程不是锁的持有者,会抛出异常。注意:必须写在synchronized方法内部或者synchronized块内部,wait和notify必须注意通知的对象。Interrupt方法属于Thread的,执行不需要获取锁,会抛出异常。Interrupt只会在对处于阻塞状态的线程抛出异常。
1.7 join方法,使当前线程加入父线程,父线程进入阻塞状态,类似于插队
1.8 用户线程:主线程停止也不会受到影响,
守护线程,如果主线程死亡,守护线程一样会死亡。
- 线程池
2.1
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize线程池维持线程最少数量;
maximumPoolSize线程池维持线程最大数量;
keepAliveTime 线程池中空闲时存活的时间;
unit 时间单位
workQueue 存放任务的列表
threadFactory 线程工厂,用来创建新线程
handler 超出线程范围和队列容量而执行的处理策略
执行顺序
1.如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
2. 如果此时线程池中的数量大于等于corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
3. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理添加的任务。
4. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
5. 当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
2.2 常用线程池
1. newCachedThreadPool —— 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2.newFixedThreadPool —— 创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
3.newSingleThreadExecutor —— 创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
4.newScheduleThreadPool —— 创建一个定长的线程池,而且支持定时的以及周期性的任务执行,支持定时及周期性任务执行

浙公网安备 33010602011771号