上一篇
本来这篇文章快写好的了,电脑不停的输出字符,生气的砸了一下,直接关机了,内容没保存。不知为何最近这么的暴躁,昨天是静了静,休息了一下,今天上班回来,该写的还是得写啊,人要是没了梦想,活着就是为了等死吗?很喜欢肖申克的救赎里面的一句话,busy living or busy dying,静下心来,努力追求梦想吧!
前言
上一篇文章写了 Java 集合框架的内容,我觉得写的还可以吧,虽然都是点到即止,但是希望能够加深读者的印象。在看完源码的前提下,有效的把握重点,由点及面,才能胸有成竹。
1、线程状态转换
这张图画的很好,注意下里面进入和出去状态的方法,基本线程的大概就有着落了。
2、多线程的实现
-
Thread
-
Runnable 接口
-
Callable 接口
FutureTask<Integer> ft = new FutureTask<>(callable); Thread thread = new Thread(ft); thread.start(); ft.get();
3、线程的 wait、sleep、join 以及 yield
- wait():
- 进入到和该对象相关的等待池,师范对象的机锁
- 可使用 notify、notifyAll 或指定唤醒时间来唤醒
- wait、notify、notifyAll 必须在 synchronized 块中,否则异常
- sleep():Thread 静态函数,使线程进入睡眠状态,不能改变锁机制
- join():等待目标线程完成后再继续执行,target.join(later)
- yield():让出执行权限,让其他线程优先执行,但是否优先未知
4、Callable、Future 和 FutureTask
- Callable:有泛型返回值
- Future:抽象接口
- cancel()取消任务
- isCancel()
- isDone()
- V get():获取结果,阻塞等到完成
- V get(timeout, unit)
- FutureTask:实现了 RunnableFuture(间接实现了 Runnable、Future)
- RunnableFuture:接收 Callable 和 Runnable(会包装成 Callable,返回值靠传入)
5、线程池
-
① 优点
- 重用存在线程,减少对象创建、销毁的开销
- 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞
- 提供定时执行、定期执行、单线程、并发数控制等功能
-
② 线程池都实现了 ExecutorService 接口:submit(有返回值)、execute、shutdown
-
启动指定数量的线程——ThreadPoolExecutor
- corePoolSize:线程池说保存的核心线程数
- maximumPoolSize:线程池穿件的最大线程数(大于核心数存阻塞队列)
- keepAliveTime:当前线程池线程总数大于核心线程数时,终止多余的空闲线程时间
- Unit:keepAliveTime 参数时间单位
- WorkQueue:任务队列
- threadFactory:线程工厂,让用户定制线程的创建过程,通常不设置
- Handler:拒绝策略,当线程池和 workQueue 队列都满时的处理策略(默认拒绝并抛出异常)
-
任务处理过程
- num < corePoolSize:创建线程
- corePoolSize < num < maximumPoolSize:存放队列
- num > maximumPoolSize:处理策略:
- 拒绝并抛出异常
- 拒绝,再调用线程执行
- 删除头任务,重试
- 抛弃,无异常
-
Queue 的分类
-
ArrayBlockingQueue:有界,FIFO排序
-
LinkedBlockingQueue:无界,FIFO排序
-
SynchronousQueue:空的,直接将任务提交线程
-
ProprityBlockingQueue:优先级有界队列
提供的 Executor(如何由上面知识得出?)
- CachedThreadPool:一个任务一个线程(maximumPoolSize = 无限 + 空队列)
- FixedThreadPool:固定大小线程(corePoolSize = maximumPoolSize + 无界队列)
- SingleThreadExecutor:当线性执行多任务时
-
-
-
③ 定时执行一些任务——ScheduledThreadPoolExecutor
Executors.newScheduledThreadPool(n) //线程数 executorServiece.scheduleAtFixedRate(Runnable, 1, 3, TimeUnit) //第一次延迟时间,定期时间
-
④ 线程的使用准则
- 不要对那些同步等待其他任务结果的任务排序,可能会死锁
- 理解任务,任务是 CPU 限制的还是 I/O 限制的等,选用正确队列
- 调整线程池大小,避免线程太大或太小
-
⑤ shutdown():
- 关闭所有线程,不再接受,等待所有结束
- shutdownNow:基于 interrupt 标志实现
- 记得关闭线程池!!!
Daemon 守护线程
- 当所有非守护线程结束时,程序也就终止了,同时会啥事所有守护进程
- 使用:setDaemon()