本文是《java多线程编程核心技术》第五、六、七章的学习笔记。
定时器 Timer
Timer类主要负责计划任务的功能
一些方法:
- schedule(TimerTask task, Date time)在指定的日期执行某一次任务。
- schedule(TimerTask task, long delay)以执行此方法的当前时间为参考时间,在此时间基础上延迟指定的毫秒数后执行一次TimerTask任务
- schedule(TimerTask task, long delay, long period)以执行此方法的当前时间为参考时间,在此时间基础上延迟指定的毫秒数,再以某一间隔时间无限次数地执行某一TimerTask任务
- scheduleAtFixedRate(TimerTask task, Date firstTime, long period)在指定的日期之后,按指定的间隔周期,无限循环的执行某一任务
schedule和scheduleAtFixedRate的异同:
同:
- 多次调用schedule或scheduleAtFixedRate执行多个任务的话,则都是以队列的方式一个一个的被顺序执行。所以不用考虑非线程安全的问题。
- 如果任务延时了,那么下一次任务的执行时间都是上一次任务结束的时间(都带period参数时)
异:
- 不延时时,schedule下一次任务的执行时间是上一次任务开始加上period的时间,scheduleAtFixedRate下一次任务的执行时间是上一次任务结束的时间。
单例模式与多线程
单例模式是23个设计模式中的一种,本章将它与多线程结合考虑
- 立即加载/“饿汉模式”:调用方法前,实例已经被创建了。
- 延迟加载/“懒汉模式”:调用get()方法时实例才被创建。最常见的实现办法是在get()方法中进行new实例化。可是在多线程环境中会出问题,即创建多个实例。
解决方案
- 声明synchronized关键字,但运行效率非常低
- 同步代码块,但效率也非常低
- 针对某些重要代码单独的同步,效率提升,但是会创建多个实例
- 使用DCL双检查锁
| public class MyObject { | 
- 使用静态内置类
- 使用static代码块
- 使用enum枚举数据类型
拾遗增补
线程状态:
线程组:
- 线程组中可以有线程对象,也可以有线程组,组中还可以有线程。作用是可批量管理线程或线程组对象,有效地对线程或线程组对象进行组织。
- 实例化一个线程组时如果不指定所属的线程组,它会自动归属到当前线程对象所属的线程组中。
线程中出现异常的处理:
- setUncaughtExceptionHandler()给指定线程对线设置异常处理器
- setDefaultUncaughtExceptionHandler()对指定线程类的所有线程对象设置异常处理器