本文是《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()
对指定线程类的所有线程对象设置异常处理器