Java并发编程基础
Java并发编程基础
线程的状态
线程的状态变化
Daemon 线程
- Daemon 线程是一种支持型线程(常被叫做守护线程),因为它主要被用作程序中后台调度以及支持性工作。
- 可以通过调用
Thread.setDaemon(true)
将线程设置为 Daemon 线程。
中断
- 许多声明抛出
InterruptedException
的方法(例如Thread.sleep(long millis)
方法)在抛出InterruptedException
之前,Java 虚拟机会先将该线程的中断标识位清除,然后抛出InterruptedException
。此时调用isInterrupted()
方法将会返回false
。
安全地终止线程
- 使用标志位
- 使用中断
线程间通信
- volatile 和 synchronized 关键字
- 等待/通知机制
- 难以确保及时性
- 难以降低开销
- 等待/通知的相关方法是任意 Java 对象都具备的,因为这些方法被定义在所有对象的超类
java.lang.Object
上。 - 不同线程之间通过锁对象的
wait
和notify
方法进行消息传输。
细节问题
- 使用
wait()
、notify()
和notifyAll()
时需要先对调用对象加锁。 - 调用
wait()
方法后,线程状态由RUNNING
变为WAITING
,并将当前线程放置到对象的等待队列。 notify()
或notifyAll()
方法调用后,等待线程依旧不会从wait()
返回,需要调用notify()
或notifyAll()
的线程释放锁之后,等待线程才有机会从wait()
返回。notify()
方法将等待队列中的一个等待线程从等待队列中移到同步队列中,而notifyAll()
方法则是将等待队列中所有的线程全部移到同步队列,**被移动的线程状态由WAITING
变为BLOCKED
**。- 从
wait()
方法返回的前提是获得了调用对象的锁。
管道输入/输出流
PipedOutputStream
、PipedInputStream
、PipedReader
和PipedWriter
,前两种面向字节,而后两种面向字符。- 对于
Piped
类型的流,必须先进行绑定,也就是调用connect()
方法,如果没有将输入/输出流绑定起来,对于该流的访问将会抛出异常。
Thread.join() 的使用
- 如果一个线程 A 执行了
thread.join()
语句,其含义是:当前线程 A 等待 thread 线程终止之后才从thread.join()
返回。
ThreadLocal 的使用
- ThreadLocal,即线程变量,是一个以
ThreadLocal
对象为键、任意对象为值的存储结构。这个结构被附带在线程上,也就是说一个线程可以根据一个ThreadLocal
对象查询到绑定在这个线程上的一个值。 - 可以通过
set(T)
方法来设置一个值,在当前线程下再通过get()
方法获取到原先设置的值。
线程应用实例
- 等待超时模式
Java线程六种状态及切换
- 在刚刚创建了
Thread
,但是没有调用start
方法的时候,线程处于NEW
状态。 - 在调用
start
方法后,线程会进入RUNNABLE
状态。- 多次调用一个线程的
start
方法会怎么样?- 线程内部有一个
threadStatus
变量,在刚创建的new
状态的时候,该变量值为0
,在运行后,或者切换线程状态后,该threadStatus
会改变,这会导致线程在第二次调用start
方法的时候抛出异常。
- 线程内部有一个
- 一个线程执行完毕,处于
TERMINATED
状态,再次调用这个线程的start
方法是否可行?- 不可,处于
TERMINATED
状态的线程的threadStatus
是2
。
- 不可,处于
- 多次调用一个线程的
RUNNABLE 状态
- 表示当前线程正在运行中。处于
RUNNABLE
状态的线程在 Java 虚拟机中运行,也有可能在等待 CPU 分配资源。Java 线程的RUNNABLE
状态其实包括了操作系统线程的 ready 和 running 两个状态。
BLOCKED 状态
- 处于
BLOCKED
状态的线程正在等待锁的释放以进入同步区。
WAITING 状态
- 等待状态。处于等待状态的线程变成
RUNNABLE
状态需要其他线程唤醒。 - 调用下面这 3 个方法会使线程进入等待状态:
Object.wait()
Thread.join()
LockSupport.park()
TIMED_WAITING 状态
- 超时等待状态。线程等待一个具体的时间,时间到后会被自动唤醒。
- 调用如下方法会使线程进入超时等待状态:
Thread.sleep()
Object.wait()
Thread.join()
LockSupport.parkNanos(long nanos)
LockSupport.parkUntil(long deadline)
调用
wait()
方法前,线程必须持有对象的锁。
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment