本章主要介绍了什么是线程、线程的启动和终止、线程之间的通信和几个实际案例。
线程简介
什么是线程
线程:操作系统调度的最小单元,也叫轻量级进程(LightWeight Process)。
1 | public class MultiThread{ |
为什么要使用多线程
因为正确使用多线程,总是能够给开发人员带来显著的好处,而使用多线程的原因主要有以下几点。
- 更多的处理器核心
- 更快的响应时间
- 更好的编程模型
线程优先级
在Java线程中,通过一个整型成员变量priority来控制优先级,优先级的范围从1~10。可以通过setPriority(int)方法来修改优先级,默认优先级是5。程序正确性不能依赖线程的优先级高低。
1 | public class Priority { |
线程的状态
- 初始状态
- 运行状态
- 阻塞状态
- 等待状态
- 超时等待状态
- 终止状态
状态图
1 | public class ThreadState { |
Daemon线程
Daemon线程是一种支持型线程,因为它主要被用作程序中后台调度以及支持性工作。
注意:Daemon属性需要在启动线程之前设置,不能在启动线程之后设置。
1 | public class Daemon { |
启动和终止线程
start()、run()
构造线程
1 | private void init(ThreadGroup g, Runnable target, String name,long stackSize, |
启动线程
线程对象在初始化完成之后,调用start()方法就可以启动这个线程。
中断
中断可以理解为线程的一个标识位属性,它表示一个运行中的线程是否被其他线程进行了中断操作。
关键方法:
- isInterrupted():是否被中断
- Thread.interrupted():复位(对当前线程的中断标识)
- Thread.sleep(longmillis):睡眠指定时间
1 | public class Interrupted { |
过期的suspend()、resume()和stop()
大家对于CD机肯定不会陌生,如果把它播放音乐比作一个线程的运作。
- suspend():暂停
- 过期的API
- 占有着资源进入睡眠状态,容易引发死锁
- resume():恢复
- stop():停止
- 过期的API
- 不会保证线程的资源正常释放
1 |
|
安全地终止线程
中断操作是一种简便的线程间交互方式,而这种交互方式最适合用来取消或停止任务。除了中断以外,还可以利用一个boolean变量来控制是否需要停止任务并终止该线程。
1 | public class Shutdown { |
线程间通信
线程开始运行,拥有自己的栈空间,如果多个线程能够相互配合完成工作,这将会带来巨大的价值。
volatile和synchronized关键字
关键字volatile:轻量级锁,可以用来修饰字段(成员变量)。
1 | public class Synchronized { |
结论:
- 同步块:使用了monitorenter和monitorexit指令。
- 同步方法:依靠方法修饰符上的ACC_SYNCHRONIZED来完成的。
等待/通知机制
是指一个线程A调用了对象O的wait()方法进入等待状态,而另一个线程B调用了对象O的notify()或者notifyAll()方法,线程A收到通知后从对象O的wait()方法返回,进而执行后续操作。
相关方法:
1 | public class WaitNotify { |
执行流程图:
等待/通知的经典范式
该范式分为两部分,分别针对等待方(消费者)和通知方(生产者)。
等待方遵循如下原则。
- 获取对象的锁。
- 如果条件不满足,那么调用对象的wait()方法,被通知后仍要检查条件。
- 条件满足则执行对应的逻辑。
1 | synchronized(对象) { |
通知方遵循如下原则。
- 获得对象的锁。
- 改变条件。
- 通知所有等待在对象上的线程。
1 | synchronized(对象) { |
管道输入/输出流
可以理解为它是用于线程之间的数据传输,传输的媒介为内存的流。
1 | public class Piped { |
Thread.join()的使用
如果一个线程A执行了thread.join()语句,其含义是:当前线程A等待thread线程终止之后才
从thread.join()返回。
1 | public class Join { |
JDK中Thread.join()方法的源码:
1 | // 加锁当前线程对象 |
ThreadLocal的使用
ThreadLocal,即线程变量,是一个以ThreadLocal对象为键、任意对象为值的存储结构。
1 | public class Profiler { |
线程应用实例
等待超时模式
1 | public class SimpleHttpServer { |
一个简单的数据库连接池示例
1 | public class ConnectionPool { |
线程池技术及其示例
1 | public interface ThreadPool<Job extends Runnable> { |
线程池接口的默认实现:
1 | public class DefaultThreadPool<Job extends Runnable> implements ThreadPool<Job> { |
一个基于线程池技术的简单Web服务器
1 | public class SimpleHttpServer { |