等待/通知机制的实现 wait,notify/notifyAll
线程进入Runnable状态大体分为如下5种情况:
1、调用sleep()方法后经过的时间超过了指定的休眠时间
2、线程调用的阻塞IO已经返回,阻塞方法执行完毕
3、线程成功地获得了试图同步的监视器
4、线程正在等待某个通知,其他线程发出了通知
5、处于挂起状态的线程调用了resume恢复方法
进入Runnale状态,等待系统重新分配资源分为5种
1、线程调用sleep方法,主动放弃占用的处理器资源
2、线程调用了阻塞式IO方法,在该方法返回前,该线程被阻塞
3、线程试图获得一个同步监视器,但该同步监视器正被其他线程所持有
4、线程等待某个通知
5、程序调用了suspend方法将该线程挂起(此方法容易导致死锁)
yield()让当前线程状态改为可运行状态,和其它线程一起竞争资源
join()方法执行当前线程,并使得其他线程处于阻塞状态
join(long millis)方法执行当前线程millis后,再和其它线程一起竞争资源
当方法wait()被执行后,锁被自动释放,但执行完notify()方法,锁却不自动释放
wait(long)方法是指等待某一时间内是否有线程对锁进行唤醒,如果超过这个时间则自动唤醒
java的JDK中提供了4个类来使线程间可以进行通信:
pipedinputstream、pipedoutputstream(字节流)、pipedreader、pipedwriter(字符流)
volatile基本数据类型从主存中取,而不是各个线程的“工作内存”,其具有可见性,但没有并发和正确性
join和synchronized的区别:join在内部使用wait()方法进行等待,而synchronized关键字使用的是“对象监控器”原理为同步
wait(long)释放锁,而sleep(long)不释放锁
ThreadLocal线程绑定自己的值,如盒子中可以存储每个线程的私有数据
============JDK1.5版本以上================
ReentrantLock类的使用 在功能上比synchronized更多
ReentrantReadWriteLock类的使用
使用Condition实现等待/通知:错误用法与解决 await/signal
使用ReentrantLock结合Condition类是可以实现“选择性通知”,Condition默认提供
公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即先来先得FIFO顺序
非公平锁是一种获取锁的抢占机制,是随机获得锁的,先来不一定显得锁,也有可能某个线程一直拿不到锁(默认)
getHoldCount()方法是查询当前线程保持此锁定的个数
getQueueLength()方法是查询返回正等待获取此锁定的线程估计数
getWaitQueueLength()方法是查询返回等待与此锁定相关的给定条件Condition的线程估计数
hasQueueThread()方法是查询指定的线程正在等待获取此锁定
hasWaiters(Condition condition)方法是查询是否有线程正在等待与此锁定有关的condition条件
isHeldByCurrentThread()的作用是查询当前线程是否保持此锁定
isLocked()的作用是查询此锁定是否由任意线程保持
lockInterruptibly()的作用是如果当前线程未被中断,则获取锁定,如果已经被中断则出现异常
tryLock()的作用是仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定
tryLock(long timeout,TimeUnit unit)的作用是如果锁定在给定等待时间内没有被另一个线程保持,且当前线程
未被中断,则获取该锁定
ReentrantLock具有完全互斥排他的效果,即同一时间只有一个线程在执行ReentrantLock.lock()方法后面的任务
写写互斥,读写互斥
定时器timer
1、如何实现指定时间执行任务
2、如何实现按指定周期执行任务
TimerTask是以队列的方式一个一个被顺序执行的,所以执行的时间由可能和预期的时间不一致
schedule(TimerTask task,Date firstTime,long period)是在指定的日期之后,按指定的间隔周期性地无限循环地
执行某一任务(如果计划时间早于当前时间,则立即执行task任务)
TimerTask类中的cancel()方法的作用是将自身从任务队列中清除
Timer类中的cancel()方法有时并不一定会停止执行计划任务,而是正常执行,原因是争取不到queue锁
使用schedule方法:如果执行任务的时间没有被延时,那么下一次任务的执行时间参考的是上一次任务的“结束”时的时间来计算
schedule方法不具有追赶执行性,而scheduleAtFixedRate方法具有追赶执行性
静态代码块中的代码再使用类的时候就已经执行了
枚举enum和静态代码块的特性相似,在使用枚举类时,构造方法会被自动调用
1、线程组的使用
2、如何切换线程状态
3、SimpleDataFormat类与多线程的解决办法
4、如何处理线程的异常
Thread.State
NEW:至今尚未启动的线程处于这种状态
RUNNABLE:正在JAVA虚拟机中执行的线程处于这种状态
BLOCKED:受阻塞并等待某个监视器锁的线程处于这种状态
WAITIME:无限期地等待另一个线程来执行某一特定操作的线程处于这种状态
TIME WAITIME:等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态
TERMINATED:已退出的线程处于这种状态
线程组的作用是可以批量的管理线程或线程组对象,有效地对线程或线程组对象进行组织
在实例化一个ThreadGroup线程组x时如果不指定所属的线程组,线程组自动归到当前线程对象所属的线程组中
setUncaughtExceptionHandler方法是给指定线程对象设置的异常处理器
setDefaultUncaughtExceptionHandler方法是给所有线程对象设置的异常处理器
参照书籍来源:《Java多线程编程核心技术》