标签: javahtml
[TOC]java
本文对多线程基础知识进行梳理,主要包括多线程的基本使用,对象及变量的并发访问,线程间通讯,lock的使用,定时器,单例模式,以及线程状态与线程组。git
花了一周时间阅读《java多线程编程核心技术》(高洪岩 著),本文算是此书的整理概括,书中几乎全部示例,我都亲手敲了一遍,并上传到了个人github上,有兴趣的朋友能够到个人github下载。源码采用maven构建,多线程这部分源码位于java-multithread
模块中。github
- 仓库地址:java-learning
- git clone:
git@github.com:brianway/java-learning.git
基础知识编程
isAlive()
测试线程是否处于活动状态sleep()
让“正在执行的线程”休眠getId()
取得线程惟一标识yield()
放弃当前的CPU资源stop()
,suspend()
,resume()
等,已经弃用了,由于可能产生数据不一样步等问题。比较和辨析api
currentThread()
方法返回值肯定。例如,直接在main方法里调用run方法,和调用线程的start方法,打印出的当前线程结果是不一样的。interrupted()
和isInterrupted()
interrupted()
是类的静态方法,测试当前线程是否已是中断状态,执行后具备将状态标志清除为false的功能。isInterrupted()
是类的实例方法,测试Thread对象是否已是中断状态,但不清楚状态标志。sleep()
和wait()
区别:
java.lang.IllegalMonitorStateException
异常方法 | 是否释放锁 | 备注 |
---|---|---|
wait | 是 | wait和notify/notifyAll是成对出现的, 必须在synchronize块中被调用 |
sleep | 否 | 可以使低优先级的线程得到执行机会 |
yield | 否 | yield方法使当前线程让出CPU占有权, 但让出的时间是不可设定的 |
synchronized
关键字
synchronized(x){}
同步代码块时呈同步效果线程的私有堆栈图安全
读取公共内存图多线程
辨析和零散补充并发
变量在内存中的工做过程图oracle
wait()
和notify()
/notifyAll()
。wait使线程中止运行,notify使中止的线程继续运行。
wait()
:将当前执行代码的线程进行等待,置入"预执行队列"。
wait(long)
是等待某一时间内是否有线程对锁进行唤醒,超时则自动唤醒。notify()
:通知可能等待该对象的对象锁的其余线程。随机挑选一个呈wait状态的线程,使它等待获取该对象的对象锁。
notifyAll()
和notify()
差很少,只不过是使全部正在等待队中等待同一共享资源的“所有”线程从等待状态退出,进入可运行状态。PipedInputStream
和PipedOutputStream
PipedReader
和PipedWriter
join()
:等待线程对象销毁,具备使线程排队运行的做用。
join(long)
可设定等待的时间join
与synchronized
的区别:join在内部使用wait()方法进行等待;synchronized使用的是“对象监视器”原理做为同步join(long)
与sleep(long)
的区别:join(long)内部使用wait(long)实现,因此join(long)具备释放锁的特色;Thread.sleep(long)不释放锁。ThreadLocal
类:每一个线程绑定本身的值
initialValue()
方法可使变量初始化,从而解决get()返回null的问题InheritableThreadLocal
类可在子线程中取得父线程继承下来的值。ReentrantLock
类:实现线程之间的同步互斥,比synchronized更灵活
lock()
,调用了的线程就持有了“对象监视器”,效果和synchronized同样Condition
实现等待/通知:比wait()和notify()/notyfyAll()更灵活,好比可实现多路通知。
Object与Condition方法对比
Object | Condition |
---|---|
wait() | await() |
wait(long timeout) | await(long time,TimeUnit unit) |
notify() | signal() |
notifyAll() | signalAll() |
一些API
方法 | 说明 |
---|---|
int getHoldCount() |
查询当前线程保持此锁定的个数,即调用lock()方法的次数 |
int getQueueLength() |
返回正在等待获取此锁定的线程估计数 |
int getWaitQueueLength(Condition condition) |
返回等待与此锁定相关的给定条件Conditon的线程估计数 |
boolean hasQueueThread(Thread thread) |
查询指定的线程是否正在等待获取此锁定 |
boolean hasQueueThreads() |
查询是否有线程正在等待获取此锁定 |
boolean hasWaiters(Condition) |
查询是否有线程正在等待与此锁定有关的condition条件 |
boolean isFair() |
判断是否是公平锁 |
boolean isHeldByCurrentThread() |
查询当前线程是否保持此锁定 |
boolean isLocked() |
查询此锁定是否由任意线程保持 |
void lockInterruptibly() |
若是当前线程未被中断,则获取锁定,若是已经被中断则出现异常 |
boolean tryLock() |
仅在调用时锁定未被另外一个线程保持的状况下,才获取该锁定 |
boolean tryLock(long timeout,TimeUnit unit) |
若是锁定在给定等待时间内没有被另外一个线程保持,且当前线程未被中断,则获取该锁定 |
ReentrantReadWriteLock
类
经常使用API
方法 | 说明 |
---|---|
schedule(TimerTask task, Date time) | 在指定的日期执行某一次任务 |
scheduleAtFixedRate(TimerTask task, Date firstTime, long period) | 在指定的日期以后按指定的间隔周期,无限循环的执行某一任务 |
schedule(TimerTask task, long delay) | 以执行此方法的当前时间为基准时间,在此时间基础上延迟指定的毫秒数后执行一次TimerTask任务 |
schedule(TimerTask task, long delay, long period) | 以执行此方法的当前时间为基准时间,在此时间基础上延迟指定的毫秒数,再以某一间隔时间无限次数地执行某一TimerTask任务 |
schedule
和scheduleAtFixedRate
的区别:schedule不具备追赶执行性;scheduleAtFixedRate具备追赶执行性方法与状态关系示意图
Thread.State
枚举类,参阅官网APIEnum Thread.StateSimpleDateFormat
非线程安全,解决办法有:
setUncaughtExceptionHandler()
给指定线程对线设置异常处理器setDefaultUncaughtExceptionHandler()
对全部线程对象设置异常处理器