同步器是一些使线程能够等待另一个线程的对象,允许它们协调动作。最常用的同步器是CountDownLatch和Semaphore,不常用的是Barrier和Exchanger
队列同步器AbstractQueuedSynchronizer是用来构建锁或者其他同步组件的基础框架,它内部使用了一个volatiole修饰的int类型的成员变量state来表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。
同步器的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理同步状态,在抽象方法的实现过程中免不了要对同步状态进行修改,这时就需要使用同步器来提供的3个方法(getState()、setState(intnewState)/和compareAndSetState(intexpect,intupdate))来进行操作,因为他们能够保证状态的改变是安全的。子类推荐被定义为自定义同步组件的静态内部类,同步器自身没有实现任何同步接口,它仅仅是定义了若干同步状态获取个释放的方法来供自定义同步组件使用,同步器既可以独占式的获取同步状态,也可以支持共享式的获取同步状态,这样就可以方便实现不同类型的同步组件(ReentrantLock、ReadWriteLock、和CountDownLatch等)。
同步器是实现锁的关键,在锁的实现中聚合同步器,利用同步器实现锁的语义。他们二者直接的关系就是:锁是面向使用者的,它定义了使用者与锁交互的接口,隐藏了实现的细节;同步器则是面向锁的实现者,它简化了锁的实现方式,屏蔽了同步状态管理、线程的排队、等待与唤醒等底层操作。锁和同步器很好的隔离了使用者与实现者所需关注的领域。
同步器的设计是基于模版方法模式实现的,使用者需要继承同步器并重写这顶的方法,随后将同步器组合在自定义同步组件的实现中,并调用同步器提供的模版方法,而这些模版方法将会调用使用者重写的方法。
同步器提供的模版方法基本上分为3类:独占式获取锁与释放同步状态、共享式获取与释放同步状态和查询同步队列中的等待线程情况。自定义同步组件将使用同步器提供的模版方法来实现自己的同步语义。倒计数器锁存器是一次性障碍,允许一个或者多个线程等待一个或者多个其它线程来做某些事情。CountDownLatch的唯一构造器带一个int类型的参数,这个int参数是指允许所有在等待线程被处理之前,必须在锁存器上调用countDown方法的次数。
EG:
package hb.java.thread;import java.util.concurrent.CountDownLatch;public class CountDownLatchTest {private static final int THREAD_COUNT = 10;// 在调用startSingal.countDown()之前调用了startSingal.await()的线程一律等待,直到startSingal.countDown()的调用private static final CountDownLatch startSingal = new CountDownLatch(1);// 在finishedSingal的初始化记数量通过调用finishedSingal.countDown()减少为0时调用了finishedSingal.await()的线程一直阻塞private static final CountDownLatch finishedSingal = new CountDownLatch(THREAD_COUNT);public static void main(String[] args) throws InterruptedException {for (int i = 0; i < THREAD_COUNT; i++) {new Thread("Task " + i) {public void run() {System.out.println(Thread.currentThread().getName()+ " prepared!!");try {startSingal.await();}catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+ " finished!!");finishedSingal.countDown();};}.start();}Thread.sleep(1000);startSingal.countDown();// 所有的线程被唤醒,同时开始工作.countDown 方法的线程等到计数到达零时才继续finishedSingal.await();// 等待所有的线程完成!!System.out.println("All task are finished!!");}}
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1148
183.71 KB下载数642
644.84 KB下载数2756
相关文章
发现更多好内容- 如何在 Java EMqtt 中实现消息确认机制?(Java EMqtt怎样实现消息确认机制)
- Java 性能调优的有效手段有哪些?(Java性能调优有何有效手段)
- 探讨Uncomtrade数据库的安全防护措施
- Java 如何获取某个接口的实现类?(Java怎么获取某个接口的实现类)
- Java中如何正确使用 collections.shuffle 方法?(Java中collections.shuffle怎么使用)
- Java Swing 中常用的布局有哪些?(java swing常用布局有哪些)
- 如何通过 Java Reflection 获取泛型信息?(java reflection如何获取泛型信息)
- 如何自定义 Java 泛型通配符?(java泛型通配符怎么自定义)
- Java Spring 注解与 XML 配置的差异究竟有哪些?(java spring注解与XML配置的区别是什么)
- Java 动态线程池对性能究竟有哪些影响呢?(Java动态线程池对性能的影响)