线程同步辅助类
线程同步辅助类
信号量(Semaphore):是一种计数器,用来保护一个或者多个共享资源的访问。它是并发编程的一种基础攻击,大多数编程语言都提供了这个机制。
CountDownLatch:是java语言提供的同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。
CyclicBarrier:是java语言提供的同步辅助类,它允许多个线程在某个集合点处进行相互等待。
Phaser:是java语言提供的同步辅助类,它把并发任务分成多个阶段运行,在开始下一阶段之前,当前阶段中的所有线程都必须执行完成,这是java7 APi中的新特性。
Exchanger:是java语言提供的同步辅助类,它提供了两个线程之间的数据交换点。
1.信号量Semaphore类
如果线程要访问一个共享资源,它必须先获取信号量。如果信号量的内部计数器大于0,信号量将减1,然后允许访问这个共享资源。计数器大于0意味着可以使用的资源,因此线程将被允许使用其中一个资源。
否则,如果信号量的计数器等于0,信号量将会把线程置入休眠直至计数器大于0。计数器等于0的时候意味着所有的共享资源已经被其他线程使用了,所以需要访问这个共享资源的线程必须等待。
当线程使用完某个共享资源时,信号量必须被释放,以便其他线程能够访问共享资源。释放操作将使信号量的内部计数器增加1。
信号量实现临界区必须遵循的三个步骤,从而保护对共享资源的访问:
首先,必须通过acquire()方法获取信号量;
其次,使用共享资源执行必要的操作;
最后,必须通过release()方法释放信号量。
信号量的公平性
Semaphore类的构造器提供了第二个传入参数。这个参数是boolean型的。如果传入false值,那么创建的信号量就是非公平模式的,与不使用这个参数的效果一样。如果传入true值,那么创建的信号量是公平模式的。
2.CountDownLatch类
java并发API提供了CountDownLatch类,它是一个同步辅助类。在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。这个类使用一个整数进行初始化,这个整数就是线程要等待完成的操作的数目。当一个线程要等待某些操作先执行完时,需要调用await()方法,这个方法让线程进入休眠直到等待的所有操作都完成。当某一个操作完成后,它将调用countDown()方法将CountDownLatch类的内部计数器减1.当计数器变成0的时候,CountDownLatch类将唤醒所有调用await()方法而进入休眠的线程。
3.CyclicBarrier类
java并发API提供了CyclicBarrier类,它是一个同步辅助类。它允许两个或者多个线程在某个点上进行同步。
CyclicBarrier类使用了一个整型数进行初始化,这个数是需要在某个点上同步的线程数。当一个线程到达指定的点后,它将调用await()方法等待其他的线程。当线程调用await()方法后,CyclicBarrier类将阻塞这个线程并使之休眠直到所有其他线程到达。当最后一个线程调用CyclicBarrier类的await()方法时,CyclicBarrier对象将唤醒所有在等待的线程,然后这些线程将继续执行。
CyclicBarrier类提供了getNumberWaiting()方法和getparties()方法,前者将返回在await()上阻塞的线程的数目,后者返回被CyclicBarrier对象同步的任务数。
CyclicBarrier对象的重置,是通过CyclicBarrier类提供的reset()方法完成的。当重置发生后,在awai()方法中等待的线程将收到一个BrokenBarrierException异常。
CyclicBarrier类提供了isBroken()方法,如果处于损坏状态就行true,否则返回false.
4.Phaser类
java并发API还提供了一个更复杂、更强大的同步辅助类,即Phaser,它允许执行并发多阶段任务。当我们有并发任务并且需要分解成几步执行时,这种机制就非常适用。Phaser类机制是在每一步结束的位置对线程进行同步,当所有的线程都完成了这一步,才允许执行下一步。
常用方法:
arriveAndDeregister()方法:调用Phaser对象的arriveAndDeregister()方法来通知Phaser对象当前线程已经结束这个阶段,并且将不再参与接下来的阶段操作。相当于取消该线程的注册。
arriveAndAwaitAdvance()方法:调用Phaser对象的arriveAndAwaitAdvance()方法,来通知Phaser对象当前线程已经完成了当前阶段,需要被阻塞直到其他线程也都完成当前阶段。
isTerminated()方法:调用了phaser对象的isTerminated()方法,当phaser对象不存在参与同步的线程时,phaser是终止的,该方法将返回true。当取消所有线程的注册时,phaser对象就会变成终止状态。
5.Exchanger类
java并发API还提供了一个同步辅助类,它就是Exchanger,它允许在并发任务之间交换数据。具体来说,Exchanger类允许在两个线程之间定义同步点。当两个线程都到达同步点时,它们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,同时第二个线程的数据结构进入到第一个线程中。