Skip to content

Latest commit

 

History

History
33 lines (17 loc) · 2.07 KB

File metadata and controls

33 lines (17 loc) · 2.07 KB

线程与锁

Java支持多线程,每个线程分别执行自己的代码,所有线程共享堆内存。

在语言层面,对应的类是 Thread, 启动方法为 Thread#start().

多线程编码时,如果未设置正确的同步,则可能会产生一些莫名其妙的BUG。

Java programming language memory model, 即Java编程语言内存模型, 另外,还有硬件层面的内存模型。

同步

线程之间有多种通信方式, 其中最基础的叫做同步(synchronization), 通过管程(monitor)来实现.

每个Java对象都有一个相关联的管程,各个线程都可以锁定(lock)以及解锁(unlock)管程。 同一时刻,只能有单个线程持有管程的锁,试图锁定该管程的其他线程都会被阻塞(blocked)。

一个线程可以多次锁定同一个管程,解锁则是锁定的反操作。

可以对某个引用使用 synchronized 语句, 来获取具体对象上面的管程。 线程执行时,只有锁定了相应的管程才能继续运行,执行语句块中的代码。synchronized 语句块执行(正常执行/异常执行)完毕,会自动解锁一次该语句块对应的管程。

调用 synchronized 方法时会自动执行锁定操作,只要获取到对应的锁才会执行该方法的方法体。 实例方法锁定的是this所指向对象的管程, 静态方法(static) 锁定的则是对应 Class 对象的管程。 方法退出时,会自动触发一次相应管程的unlock操作。

Java语言不负责死锁的检测,由程序员负责处理。 必要时请使用高级别的锁定原语。

Java还支持其他的同步机制,例如 volatile 域以及 java.util.concurrent 包中的类。

等待与通知

每个对象都有一个关联的管程,也就有对应的等待集合(wait set),也就是线程集合。

新创建的对象,其等待集合是空的。增加或者减少等待集的过程是原子性的,对应的操作方法是 Object#wait, Object#notify, 和 Object#notifyAll。 线程中断也会影响等待集, 但 sleep 和join并不会影响。

wait