• 一个 Java 程序的运行,不仅仅是 main() 方法的运行,而是 main 线程和多个其他线程的同时运行。
  • 针对频繁阻塞(休眠或 I/O 操作)的线程需要设置较高优先级,而偏重计算的线程则设置较低优先级,避免处理器被独占。
  • 线程优先级不能作为程序正确性的依赖,因为操作系统可以完全不用理会 Java 线程对优先级的设定。
  • 线程状态
    • NEW:初始状态,线程被构建,但是还没调用 start()方法。
    • RUNNABLE:运行状态,Java 线程将操作系统中的就绪和运行两种状态笼统地称作“运行中”。
    • BLOCKED:阻塞状态,表示线程阻塞于锁。
    • WAITING:等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断)。
    • TIME_WAITING:超时等待状态,该状态不同于 WAITING,它可在指定时间自行返回。
    • TERMINATED:终止状态,表示当前线程已经执行完毕。
  • Daemon 线程:支持型线程,当 Java 虚拟机不存在非 Daemon 线程时,Java 虚拟机将会退出,但当 Java 虚拟机退出时,Daemon 线程中的 finally 块不一定会执行。
  • suspend()方法不会释放已经占有的资源(比如锁),而是占着资源进入睡眠状态,容易引发死锁问题;stop()方法在终结一个线程时不会保证线程资源的正常释放,因此可能导致程序工作不确定,因而 suspend()、stop()和 resume()方法已经不建议使用。
  • 优雅中止线程:boolean 变量(标志位)或 interrupt()方法。
  • 等待/通知机制:作用于一个对象修改了值,另一个线程感知到变化,进行相应操作的场景。
    • notify():通知一个在对象上等待的线程,使其从 wait()方法返回,前提是该线程获取到了对象的锁。
    • notifyAll():通知所有等待在该对象上的线程。
    • wait():调用该方法的线程进入 WAITING 状态,只有等待另外线程的通知或被中断才会返回,调用该方法后会释放对象的锁。
    • wait(long):超时等待一段时间,参数是毫秒。
    • wait(long, int):对于超时时间更细粒度控制,可达纳秒。
    • 等待方(消费者)遵循:获取对象的锁 → 如果条件不满足,调用 wait(),被通知后仍要检查条件 → 条件满足则执行对应逻辑。
    • 通知方(生产者)遵循:获取对象的锁 → 改变条件 → 通知所有等待在对象上的线程。
// 等待方/消费者
synchronized(对象) {
	while(条件不满足) 对象.wait()
	// 展开对应处理逻辑
}
// 通知方/生产者
synchronized(对象) {
	// 改变条件
	对象.notifyAll()
}
  • 管道输入/输出:
    • 面向字节:PipedOutputStream、PipedInputStream。
    • 面向字符:PipedReader、PipedWriter。
    • 输入输出流使用前需要先绑定,即调用 connect()方法,否则将抛出异常。
  • Thread.join():当前线程等待 Thread 线程终止后,才从 join()方法返回。
    • 实现遵循加锁、循环和处理逻辑三个步骤。
    • 线程终止时,会调用线程自身的 notifyAll()方法,通知所有等待在该线程对象上的线程。
  • ThreadLocal:线程变量,以 ThreadLocal 对象为键,任意对象为值的存储结构,一个线程可以根据一个 ThreadLocal 对象查询到绑定在这个线程上的一个值。