标签:
标签: java
本文对多线程基础知识进行梳理,主要包括多线程的基本使用,对象及变量的并发访问,线程间通信,lock的使用,定时器,单例模式,以及线程状态与线程组。
花了一周时间阅读《java多线程编程核心技术》(高洪岩 著),本文算是此书的整理归纳,书中几乎所有示例,我都亲手敲了一遍,并上传到了我的github上,有兴趣的朋友可以到我的github下载。源码采用maven构建,多线程这部分源码位于java-multithread模块中。
- 仓库地址:java-learning
- git clone:
git@github.com:brianway/java-learning.git
基础知识
isAlive()测试线程是否处于活动状态sleep()让“正在执行的线程”休眠getId()取得线程唯一标识yield()放弃当前的CPU资源stop(),suspend(),resume()等,已经弃用了,因为可能产生数据不同步等问题。比较和辨析
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){}同步代码块时呈同步效果线程的私有堆栈图

读取公共内存图

辨析和零散补充
变量在内存中的工作过程图

wait()和notify()/notifyAll()。wait使线程停止运行,notify使停止的线程继续运行。 wait():将当前执行代码的线程进行等待,置入”预执行队列”。 wait(long)是等待某一时间内是否有线程对锁进行唤醒,超时则自动唤醒。notify():通知可能等待该对象的对象锁的其他线程。随机挑选一个呈wait状态的线程,使它等待获取该对象的对象锁。 notifyAll()和notify()差不多,只不过是使所有正在等待队中等待同一共享资源的“全部”线程从等待状态退出,进入可运行状态。PipedInputStream和PipedOutputStreamPipedReader和PipedWriterjoin():等待线程对象销毁,具有使线程排队运行的作用。 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.State SimpleDateFormat非线程安全,解决办法有: setUncaughtExceptionHandler()给指定线程对线设置异常处理器setDefaultUncaughtExceptionHandler()对所有线程对象设置异常处理器标签:
原文地址:http://blog.csdn.net/h3243212/article/details/51180173