zl程序教程

您现在的位置是:首页 >  其他

当前栏目

线程同步工具(六)控制并发阶段性任务的改变

2023-09-11 14:16:10 时间

声明:本文是《 Java 7 Concurrency Cookbook 》的第三章, 作者: Javier Fernández González 译者:郑玉婷

控制并发阶段性任务的改变

Phaser 类提供每次phaser改变阶段都会执行的方法。它是 onAdvance() 方法。它接收2个参数:当前阶段数和注册的参与者数;它返回 Boolean 值,如果phaser继续它的执行,则为 false;否则为真,即phaser结束运行并进入 termination 状态。

如果注册参与者为0,此方法的默认的实现值为真,要不然就是false。如果你扩展Phaser类并覆盖此方法,那么你可以修改它的行为。通常,当你要从一个phase到另一个,来执行一些行动时,你会对这么做感兴趣的。

在这个指南,你将学习如何控制phaser的 phase的改变,通过实现自定义版本的 Phaser类并覆盖 onAdvance() 方法来执行一些每个phase 都会改变的行动。你将要实现一个模拟测验,有些学生要完成他们的练习。全部的学生都必须完成同一个练习才能继续下一个练习。

准备

指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。

怎么做呢…

按照这些步骤来实现下面的例子::


    // 3. 实现辅助方法 studentsArrived()。它在操控台写2条信息,并返回false值来表明phaser将继续执行。
        System.out.printf("Phaser: The exam are going to start. The students are ready.\n");
    // 4. 实现辅助方法 finishFirstExercise()。它在操控台写2条信息,并返回false值来表明phaser将继续执行。
        System.out.printf("Phaser: All the students have finished the first exercise.\n");
    // 5. 实现辅助方法 finishSecondExercise()。它在操控台写2条信息,并返回false值来表明phaser将继续执行。
        System.out.printf("Phaser: All the students have finished the second exercise.\n");
    // 6. 实现辅助方法 finishExam()。它在操控台写2条信息,并返回false值来表明phaser将继续执行。
            // 11. 首先,方法写一条信息到操控台表明学生到达考场并调用 phaser 的 arriveAndAwaitAdvance()
            // 12. 然后,写信息到操控台,调用私有 doExercise1() 方法模拟第一场测验,写另一条信息到操控台并调用 phaser

它是怎么工作的…

这个练习模拟了有3个测验的真实测试。全部的学生必须都完成同一个测试才能开始下一个测试。为了实现这个必须使用同步,我们使用了Phaser类,但是你实现了你自己的phaser通过扩展原来的类,并覆盖onAdvance() 方法.

在阶段改变之前和在唤醒 arriveAndAwaitAdvance() 方法中休眠的全部线程们之前,此方法被 phaser 调用。这个方法接收当前阶段数作为参数,0是第一个phase ,还有注册的参与者数。最有用的参数是actual phase。如果你要基于不同的当前阶段执行不同的操作,那么你必须使用选择性结构(if/else 或 switch)来选择你想执行的操作。例子里,我们使用了 switch 结构来为每个phase的改变选择不同的方法。

onAdvance() 方法返回 Boolean 值表明 phaser 终结与否。如果返回 false 值,表示它还没有终结,那么线程将继续执行其他phases。如果phaser 返回真值,那么phaser将叫醒全部待定的线程们,并且转移phaser到terminated 状态,所以之后的任何对phaser的方法的调用都会被立刻返回,还有isTerminated() 方法将返回真值。

在核心类,当你创建 MyPhaser 对象,在phaser中你不用表示参与者的数量。你为每个 Student 对象调用了 register() 方法创建了phaser的参与者的注册。这个调用不会在Student 对象或者执行它的线程与phaser之间这个建立任何关系。 说真的,phaser的参与者数就是个数字而已。phaser与参与者之间没有任何关系。

下面的裁图展示了例子的执行结果:

你可以发现学生们结束第一个练习的时间是不同的。当全部都结束练习时,phaser 调用onAdvance() 方法写信息到操控台,接着全部的学生在同一时间开始第二场测试。

参见

第三章,线程同步应用:运行并发阶段性任务
第八章,测试并发应用:监控 Phaser

文章转自 并发编程网-ifeve.com


并发编程从操作系统底层工作整体认识开始 在多线程、多处理器、分布式环境的编程时代,并发是一个不可回避的问题。既然并发问题摆在面前一个到无法回避的坎,倒不如拥抱它,把它搞清楚,花一定的时间从操作系统底层原理到Java的基础编程再到分布式环境等几个方面深入探索并发问题。先就从原理开始吧。 计算机系统层次结构 早期计算机系统的层次 最早的计算机用机器语言编程,机器语言称为第一代程序设计语言
【高并发】线程的生命周期其实没有我们想象的那么简单!! 在【高并发专题】中的《高并发之——线程与多线程》一文中,我们简单介绍了线程的生命周期和线程的几个重要状态,并以代码的形式实现了线程是如何进入各个状态的。今天,我们就结合操作系统线程和编程语言线程再次深入探讨线程的生命周期问题,线程的生命周期其实没有我们想象的那么简单!!
谈谈JVM内部锁升级过程 对象在内存中的内存布局是什么样的?如何描述synchronized和ReentrantLock的底层实现和重入的底层原理?为什么AQS底层是CAS+volatile?锁的四种状态和锁升级过程应该如何描述?Object o = new Object() 在内存中占用多少字节?自旋锁是不是一定比重量级锁效率高?打开偏向锁是否效率一定会提升?重量级锁到底重在哪里?重量级锁什么时候比轻量级锁效率高,同样反之呢?带着这些问题往下读。