`
jimichan
  • 浏览: 280360 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Concurrent In Java 6 分享,第四部分 同步辅助类介绍

    博客分类:
  • java
阅读更多

第一部分 集合 http://jimichan.iteye.com/blog/951948

 

第二部分 线程池 http://jimichan.iteye.com/blog/951950

 

第三部分 锁 http://jimichan.iteye.com/blog/951954

 

第四部分 同步辅助类 http://jimichan.iteye.com/blog/951955

Concurrent In Java,第四部分 同步辅助类

 

2011-3-9  延昭 & 陈汝烨 版权所有,特别禁止发布到百度文库

这篇是来自公司内部分享会议是写的总结,有些内容没有表达出来,大家可以来踩,但是需留下原因,以便后续补充。

4. 同步辅助类

你提交了一些任务,但你想等它们都完成了再做另外一些事情;你提交了一些任务,但是不想让它们立刻执行,等你喊123开始的时候,它们才开始执行;等等这些场景,线程之间需要相互配合,或者等待某一个条件成熟执行。这些场景想你就需要用到同步辅助类。

 

4.1 CountDownLatch

 

CountDownLatch 内部有个计数器,通过构造函数来指定。这个类就好比是倒计时的电子牌,当倒计时为0的时候就可以一起做一些事情。

 

摘自JavaDoc的方法介绍

void

await()

         使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断

boolean

await(long timeout, TimeUnit unit)

         使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。

void

countDown()

         递减锁存器的计数,如果计数到达零,则释放所有等待的线程。

long

getCount()

         返回当前计数。

 

 

摘自JavaDoc的例子

 

class Driver { // ...
  void main() throws InterruptedException {
    CountDownLatch startSignal = new CountDownLatch(1);
    CountDownLatch doneSignal = new CountDownLatch(N);

    for (int i = 0; i < N; ++i) // create and start threads
      new Thread(new Worker(startSignal, doneSignal)).start();

    doSomethingElse();            // don't let run yet
    startSignal.countDown();      // let all threads proceed
    doSomethingElse();
    doneSignal.await();           // wait for all to finish
  }
}

class Worker implements Runnable {
  private final CountDownLatch startSignal;
  private final CountDownLatch doneSignal;
  Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
     this.startSignal = startSignal;
     this.doneSignal = doneSignal;
  }
  public void run() {
     try {
       startSignal.await();
       doWork();
       doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
  }

  void doWork() { ... }
}

 

当CountDownLatch(1)的时候,它就好比是个信号枪了。

 

4.2 CyclicBarrier

 

这个同步辅助类,它让多个线程可以在多个屏障点进行等待,所以叫cyclic,而且有个附加选择你可以在线程到达屏障点后执行一个任务(在释放其他线程之前)

new CyclicBarrier(N, 
                                new Runnable() {
                                  public void run() { 
                                    mergeRows(...); 
                                  }
});

 

为了帮助你理解,假设一个场景。

 

有一个任务,A、B、C分别从三个仓库(甲乙丙)搬运不同3个不同的零件到客户X的公司,然后再一起组装机器,完成后一起坐车去公司总部。

 

这个任务需要ABC三个线程同时进行,但是由于从仓库到客户X那边距离不等、交通状态未知的情况下,所花费的时间也不等。同时由于三个人负责的零件不同,所以安装机器的时候花费时间也不一样。这个场景中有两个需要线程间等待的地方。CyclicBarrier就可以闪亮登场了。

 

public class Main3 {

        public static void main(String[] args) {

                

                CyclicBarrier barrier = new CyclicBarrier(3,new Runnable() {

                        

                        @Override

                        public void run() {

                                System.out.println("到达公共屏障点");                                

                        }

                });

                

                ExecutorService es = Executors.newCachedThreadPool();

                

                es.submit(new Worker("A", 5000, 8000, barrier));

                es.submit(new Worker("B", 2000, 16000, barrier));

                es.submit(new Worker("C", 9000, 2000, barrier));

                

                es.shutdown();

        }

 

        static class Worker implements Runnable {

                String name;

                int t1;// 搬运零件所需要的时间

                int t2;// 参与组装工作需要的时间

 

                CyclicBarrier barrier;

 

                public Worker(String name, int t1, int t2, CyclicBarrier barrier) {

                        super();

                        this.name = name;

                        this.t1 = t1;

                        this.t2 = t2;

 

                        this.barrier = barrier;

                }

 

                @Override

                public void run() {

                        try {

                                print(name + " 开始搬运零件");

 

                                Thread.sleep(t1);// 模拟搬运时间

 

                                print(name + " 到达目的地");

 

                                int a = barrier.await(); // 等待其他人

                                if(a==0){

                                        //说明是最后一个到的可以执行特殊操作

                                }

                                

                                

                                print(name + " 开始组装机器");

                                

                                Thread.sleep(t2);// 模拟组装时间.

                                print(name + " 完成组装机器");

                                

                                barrier.await(); // 等待其他人组装完毕

                                

                                print(name + " 一起回总公司");

 

                        } catch (Exception e) {

                                e.printStackTrace();

                        }

 

                }

 

        }

        

        static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");  

        static void print(String x) {  

       System.out.println( sdf.format(new Date()) + ": "+x);

   }  

}

 

4.3 Semaphore

 

一个经典的信号量计数器。一般被用来控制对共享资源同时访问线程数量的控制。

 

特殊情况下信号量设置为1,那么就类似互斥锁的功能。

 

此类的构造方法可选地接受一个公平 参数。当设置为 false 时,此类不对线程获取锁的顺序做任何保证。和之前提到的争用获取顺序一样,在非公平模式下,系统将获得更好的吞吐量,jvm也会保证在非公平模式下让所有线程得到访问机会。

 

 

参考书目

 

JavaDoc http://www.oschina.net/uploads/doc/javase-6-doc-api-zh_CN/overview-summary.html

 

java.util.concurrent 您不知道的 5 件事

http://www.ibm.com/developerworks/cn/java/j-5things4.html?ca=drs-

http://www.ibm.com/developerworks/cn/java/j-5things15/index.html

 

0
1
分享到:
评论
1 楼 peak 2011-03-12  
不错

相关推荐

    java的concurrent用法详解

    `CyclicBarrier`也是一个同步辅助类,它允许一组线程互相等待,直到达到某个公共的屏障点。与`CountDownLatch`不同的是,`CyclicBarrier`可以在所有线程都到达屏障点后重置屏障,以便再次使用。 **2.4.3 `Semaphore...

    关于 java.util.concurrent 您不知道的 5 件事,第 2 部分

    CountDownLatch是一个同步辅助类,允许一个或多个线程等待其他线程完成操作。它是一个一次性使用的计数器,当计数值为0时,所有等待的线程才能继续执行。CyclicBarrier则允许一组线程等待彼此到达屏障点后一起继续...

    Concurrent+Programming+in+Java+-+Design+Principles+and+Patterns,+Second+Edition_

    第四章重点介绍了如何在Java中创建和管理线程,包括线程的创建方式、线程间的通信以及如何利用线程来实现并发编程。 ##### 4.1 单向消息 单向消息是一种简单的线程间通信机制,其中发送者将消息传递给接收者,但不...

    第20章 Part4 并发工具同步器.pdf

    它是一个一次性使用的同步辅助工具,可以通过`await()`方法阻塞当前线程,直到所有计数器减到0。 - **CyclicBarrier**:让一组线程在预定义的执行点进行等待,当所有线程到达这个点时,它们会被同时释放继续执行。 -...

    java实现多线程下载

    在Java编程中,多线程下载是一种常见的优化技术,它通过将大文件分割成多个小部分,然后在不同的线程中并行下载这些部分来提高下载速度。这种技术尤其适用于网络带宽有限或者文件体积庞大的情况。下面我们将深入探讨...

    15个顶级JAVA多线程面试题及回答[文].pdf

    第四,关于死锁问题的讨论也是Java多线程面试的一个重要环节。面试者需要能够理解死锁产生的条件,即互斥条件、请求与保持条件、不剥夺条件和循环等待条件,并且能够给出解决死锁的策略。 第五,volatile关键字也是...

    Java面试宝典2017pdf

    同步的实现方法主要是使用synchronized关键字和java.util.concurrent包下的各种锁。 51. 启动一个线程应该使用start()方法而不是run(),start()方法会创建新线程并调用run()。 上述知识点覆盖了Java面试宝典2017版...

    Java装逼指南.pdf

    - **CountDownLatch**、**CyclicBarrier**等同步辅助类,用于控制线程间的同步行为。 ### 总结 以上仅为文档部分内容的知识点概括,涉及Java基础语法、集合框架、并发编程等多个方面。这些知识点不仅对于Java...

    Java核心技术 卷II 高级特性(原书第9版)

    《Java核心技术 卷II 高级特性(原书...尽管这部分内容并不直接涉及《Java核心技术 卷II 高级特性(原书第9版)》书中的知识点,但它却是Java学习者在寻找学习资源和提升技能时的辅助材料,对学习Java的人而言同样重要。

    Java分布式程序设计 高清晰版

    Java提供了丰富的并发工具类,如`java.util.concurrent`包,包括线程池、并发集合、同步器等,用于高效管理线程和数据同步。 5. **分布式缓存**:如 Hazelcast 或 Ehcache,它们可以在分布式系统中提供高速的数据...

    EffectiveJava:有效的 Java 示例

    - **并发工具类**:使用`java.util.concurrent`包中的工具类,如`ExecutorService`、`Future`和`Semaphore`等,替代传统的同步机制。 7. **枚举与注解** - **枚举优于常量类**:枚举提供更丰富的功能,如方法、...

    concurrency-api:基于Vanilla Java的Java应用程序的抽象并发API

    6. **CountDownLatch**:这是一个同步辅助类,用于协调多个线程,让它们等待其他线程完成特定操作后才继续执行。 7. **CyclicBarrier**:循环栅栏,允许一组线程等待其他线程到达某个屏障点,然后一起继续执行。 8...

    北航程序设计语言原理作业 第五次作业

    - **CountDownLatch**:是一种同步辅助工具类,允许一个或多个线程等待其他线程完成操作。 - **ConcurrentHashMap**:是Java中用于存储键值对的一种并发安全的散列表。 4. **代码解析**: 1. **...

    file-management:家用文件服务

    4. **多用户同步与共享**:为了实现文件共享,可以利用Java的并发控制机制,如`synchronized`关键字和`java.util.concurrent`包中的工具类。文件的版本控制也非常重要,Java的`java.util.Versions`类可以辅助实现这...

    Synchronization_2.rar_PDF_

    5. **Java并发工具类**:对于系统操作讲师,理解Java的并发工具类如`java.util.concurrent`包下的Semaphore、CountDownLatch、CyclicBarrier等是必不可少的。文件可能通过实例解析这些工具的使用方法。 6. **分布式...

    juc2

    标题“juc2”可能指的是Java并发编程领域中的“Java Util Concurrency”(JUC)的第二部分,这个标签“HTML”可能与该主题的文档展示或者教程制作有关。由于没有提供具体的压缩包内容,我将基于这两个线索,主要围绕...

    美团点评2017秋招笔试真题-后台开发&系统工程师A.docx

    题目要求找出`java.util.concurrent`包下的四个类中差别最大的一个,选项分别为:`CountDownLatch`、`Future`、`Semaphore`、`ReentrantLock`。 - **CountDownLatch**:它是一种协调工具类,允许一个或多个线程等待...

Global site tag (gtag.js) - Google Analytics