线程同步机制是一套用于协调线程间的数据访问(Data Access)及活动(Activity)的机制,该机制用于保障线程安全以及实现这些线程的共同目标。如果把线程比作在公路上行驶的车辆,那么线程同步机制就好比是任何车辆都需要遵循的交通规则。公路上行驶的车辆只有遵守交通规则才能够达到其目的——安全地到达目的地。
从广义上来说Java平台提供的线程同步机制包括锁、volatile关键字、final关键字、static关键字,以及一些相关API,如Object.wait()/Object.notify()等。
锁概述:
我们知道线程安全问题产生前提是多个线程并发访问共享数据。于是,我们很容易想到一种保障线程安全的方法——将多个线程对共享数据的并发访问转换为串行访问,即一个共享数据一次只能被一个线程访问,该线程访问结束后其他线程才能对其进行访问。
锁(Lock)就是利用这种思路以保障线程安全的线程同步机制,其作用包括保障原子性、可见性和有序性。
对于一个锁所保护的共享数据而言,任何线程访问这些共享数据前必须先持有该锁。一个线程只有在持有锁的情况下才能够对这些共享数据进行访问;并且,一个锁一次只能够被一个线程持有;锁的持有线程再起结束对这些共享数据的访问后必须释放其持有的锁,以便其它线程能够对这些共享数据进行访问。
一个线程在访问共享数据前必须申请相应的锁,线程的这个动作被称为锁的获得(Acquire)。一个线程获得某个锁,我们就称该线程为相应锁的持有线程,锁具有排他性(Exclusive),一个锁一次只能被一个线程持有。锁的持有线程可以对该锁所保护的共享数据进行访问,访问结束后该线程必须释放相应的锁。锁的持有线程再起获得锁之后和释放锁之前这段时间内锁执行的代码被称为临界区(Critical Section)。因此,共享数据只允许在临界区内进行访问,临界区一次只能被一个线程执行。
互斥锁(Mutex)