Java7线程学习笔记(三)

线程同步辅助类:
信号量(Semaphore):是一种计数器,用来保护一个或者多个共享资源的访问。它是并发编程的一种基础工具,大多数编程语言都提供了这个机制。
CountDownLatch:是Java语言提供的同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。
CyclicBarrier:也是Java语言提供给的同步辅助类,它允许多个线程在某个聚合点处进行相互等待。
Phaser:是Java语言提供的同步辅助类,它把并发任务分成多个阶段运行,在开始下一阶段之前,当前阶段中的所有线程都必须执行完成,这是Java7中的新特性。
Exchanger:是Java语言提供的同步辅助类。它提供了两个线程之间的数据交换点。
在应用程序中,任何时候都可以使用semaphore来保护临界区,因为它是一个基础的同步机制,而其他的同步机制,则需要根据各自的上述特性来对其选择使用。

资源的并发访问控制:
如果线程要访问一个共享资源,它必须先获得信号量。如果信号量的内部计数器大于0,信号量将减一,然后允许访问这个共享资源。计数器大于0意味着有可以使用的资源,因此线程将被允许使用其中的一个资源。
否则,如果信号量的计数器等于0,信号量将会把线程置入休眠直至计数器大于0.,此时需要访问这个共享资源额线程必须等待。
当线程使用完某个共享资源时,信号量必须被释放,以便其他线程能够访问共享资源。释放操作间使信号量的内部计数器增加1.
资源的多副本的并发访问控制:
等待多个并发事件的完成:
Java并发API提供了CountDownLatch类,它是一个同步辅助类。在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。这个类使用一个整数进行初始化,这个整数就是线程要等待完成操作的数目。当一个线程要等待某些操作先执行完成时,需要调用await()方法。这个方法让线程进入休眠直到等待的所有操作都完成。当某一个操作完成后,它将调用countDown()方法将CountDownLatch类的内部计数器减一,当计数器变成0的时候,CountDownLatch类将唤醒所有调用await()方法而进入休眠的线程。
在集合点的同步:
Java并发API提供了CyclicBarrier类,它是一个同步辅助类。它允许两个或者多个线程在某个点上进行同步,比CountDownLatch更强大。
CyclicBarrier类使用一个整形数进行初始化,这个数是需要某个点上同步的线程数。当一个线程到达指定的点后,它将调用await()方法等待其他的线程。当线程调用await()方法后,CyclicBarrier类将阻塞这个线程并使之休眠直到所有其他线程到达。当最后的一个线程调用CyclicBarrier类的await()方法时,CyclicBarrier对象将唤醒所有在等待的线程,然后这些线程将继续执行。
CyclicBarrier类有一个很有意义的改进,即它可以传入另一个Runnable对象作为初始化参数。当所有的线程都到达集合点后,CyclicBarrier类将这个Runnable对象作为线程执行。这个特性使得这个类在并行任务上可以媲美分治编程技术。
并发阶段任务的执行:
Phaser:它允许执行并发多阶段任务。当我们有并发任务并且需要分解成几步执行时,这种机制非常试用。Phaser类机制是在每一步结束的位置对线程进行同步,当所有的线程都完成了这一步,才允许执行下一步。
phaser.arriveAndAwaitAdvance();当一个对象调用这个方法的时候,Phaser对象将减一,并且把这个线程置于休眠状态,直到所有其他线程完成这个阶段。在run()方法的开头调用这个方法可以保障在所有线程创建好之前没有线程开始执行任务(即所有的线程都在同一个起跑线上)。
phaser.arriveAndDeregister();实现了对Phaser对象的通知,这个线程已经完成了当前语句,并且不会再下一个阶段中参与,因而Phaser对象在开始下一个阶段时不会等待这个线程了。
一个Phaser对象有两种状态:

  • 活跃态(Active):当存在参与同步的线程的时候,Phaser就是活跃的,并且在每个阶段结束的时候进行同步。

  • 终止态(Termination):当所有参与同步的线程都取消注册的时候,Phaser就处于终止状态,在这种状态下,Phaser没有任何参与者。更具体的说,当Phaser对象的onAdvance()方法返回true的时候,Phaser对象就处于终止态,通过覆盖这个方法可以改变默认的行为。的那个Phaser是终止态的时候,同步方法arriveAndwaitAdvance()会立即返回,而且不会做任何同步的操作。
    Phaser类的一个重大特性就是不必对它的方法进行异常处理。不=不像其他的同步辅助类,被Phaser类置于休眠的线程不会响应中断事件,也不会抛出InterruptedException异常。
    并发阶段任务中的阶段切换:
    并发任务间的数据交换:
    Exchanger:它与允许在并发任务之间交换数据,Ecxhanger类允许在两个线程之间定义同步点,当两个线程都到达同步点的时候,他们交换数据结构,
    Exchanger类在生产者-消费者问题中很有用。这是一个经典的并发场景,包含一个数据缓存区,一个或者多个数据生产者,一个或多个数据消费者。Exchanger类只能同步两个线程,如果有类似的只有一个生产者和消费者的问题,就可以使用Exchanger类。

你可能感兴趣的:(java)