java多线程之闭锁(CountDownLatch)、同步屏幕(CyclicBarrier)、信号量(Semaphore)

闭锁CountDownLatch

若有多条线程,其中一条线程需要等到其他所有线程准备完所需的资源后才能运行,这样的情况可以使用闭锁。

import java.util.concurrent.CountDownLatch;

/**
 * Created by chenjianan on 2017/1/17-15:11.
 * <p>
 * Describe: CountDownLatch 闭锁练习,
 * 使用场景:若有多条线程,其中一条线程要等其他线程执行完才能执行,那么可以用闭锁;
 * 闭锁只会阻塞一条线程,目的是为了让该条任务线程满足条件后执行;
 */
public class CountDownLatchTest {

    public void test(){

        CountDownLatch latch=new CountDownLatch(2);//初始化闭锁,并设置资源数目

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 本线程必须等待所有资源加载完后才能执行
                    latch.await();
                    // 当闭锁数量为0时,await返回,执行接下来的任务
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程3执行。。。。");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程2执行。。。。");
                System.out.println("线程2执行。。。。"+latch.getCount());
                // 本资源加载完后,闭锁-1
                latch.countDown();
                System.out.println("线程2执行。。。。"+latch.getCount());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程1执行。。。。");
                System.out.println("线程1执行。。。。"+latch.getCount());
                // 本资源加载完后,闭锁-1
                latch.countDown();
                System.out.println("线程1执行。。。。"+latch.getCount());
            }
        }).start();

    }

    public static void main(String[] args){
        new CountDownLatchTest().test();
    }
}

//执行结果
线程2执行。。。。
线程2执行。。。。2
线程2执行。。。。1
线程1执行。。。。
线程1执行。。。。1
线程1执行。。。。0
线程3执行。。。。

CyclicBarrier 同步屏幕


import java.util.concurrent.CountDownLatch;

/**
 * Created by chenjianan on 2017/1/17-15:11.
 * <p>
 * Describe: CountDownLatch 闭锁练习,
 * 使用场景:若有多条线程,其中一条线程要等其他线程执行完才能执行,那么可以用闭锁;
 * 闭锁只会阻塞一条线程,目的是为了让该条任务线程满足条件后执行;
 */
public class CountDownLatchTest {

    public void test(){

        CountDownLatch latch=new CountDownLatch(2);//初始化闭锁,并设置资源数目

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 本线程必须等待所有资源加载完后才能执行
                    latch.await();
                    // 当闭锁数量为0时,await返回,执行接下来的任务
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程3执行。。。。");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程2执行。。。。");
                System.out.println("线程2执行。。。。"+latch.getCount());
                // 本资源加载完后,闭锁-1
                latch.countDown();
                System.out.println("线程2执行。。。。"+latch.getCount());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程1执行。。。。");
                System.out.println("线程1执行。。。。"+latch.getCount());
                // 本资源加载完后,闭锁-1
                latch.countDown();
                System.out.println("线程1执行。。。。"+latch.getCount());
            }
        }).start();

    }

    public static void main(String[] args){
        new CountDownLatchTest().test();
    }
}

//执行结果
线程1执行。。。。await前
线程2执行。。。。await前
线程3执行。。。。await前
到达屏幕后执行的任务、。。
线程3执行。。。。await后
线程1执行。。。。await后
线程2执行。。。。await后

信号量Semaohore


/**
 * Created by chenjianan on 2017/1/17-17:06.
 * <p>
 * Describe: 信号量
 * 使用场景
 * 若有m个资源,但有n条线程(n>m),因此同一时刻只能允许m条线程访问资源,此时可以使用Semaphore控制访问该资源的线程数量。
 */
public class SemaphoreTest {
    public void  test() {
        // 创建信号量对象,并给予3个资源
        Semaphore semaphore = new Semaphore(3);

        // 开启10条线程
        for (int i = 0; i < 10; i++) {

           new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 获取资源,若此时资源被用光,则阻塞,直到有线程归还资源
                        semaphore.acquire();
                        System.out.println("执行任务"+ Thread.currentThread().getName());
                        System.out.println("释放资源"+ Thread.currentThread().getName());
                        // 释放资源
                        semaphore.release();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

        }

    }

    public static void main(String[] args){
        new SemaphoreTest().test();
    }
}
时间: 2024-11-05 20:40:41

java多线程之闭锁(CountDownLatch)、同步屏幕(CyclicBarrier)、信号量(Semaphore)的相关文章

Java多线程编程之CountDownLatch同步工具使用实例_java

好像倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当到达0时,所有等待者就开始执行. java.util.concurrent.CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.用给定的计数初始化CountDownLatch.由于调用了countDown()方法,所以在当前计数到达零之前,await方法会一直受阻塞.之后,会释放所有等待的线程,await的所有后续调用都将立即返回.这种现

java多线程学习之线程同步

基本上感觉自己学习的东西都是学会了立马就用,很少有机会能专门花时间去学习一些东西,近些时候不忙,准备把公司的面试题全做一遍,难的倒是不多,但是很多人都不会做,问题就是出在实践上. 言归正传.多线程就目前而言,纯是兴趣上的学习,并没有真实的应用场景.以前觉java多线程很乱,很多概念没似懂非懂,但是实战中写几个实例就一目了然了. 昨天练习线程安全时提到了synchronized关键字,其作用原理其实就是把一个或者一部份资源锁住,只允许当前这个进程使用.我理解线程同步就让各个线程之间能够控制资源的分

详解Java多线程编程中CountDownLatch阻塞线程的方法_java

直译过来就是倒计数(CountDown)门闩(Latch).倒计数不用说,门闩的意思顾名思义就是阻止前进.在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程. CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. CountDownLatch 的作用和 Thread.join() 方法类似,可用于一组线程和另外一组线程的协作.例如,主线程在做一项工作之前需要一系列的准备工作,只有这些准备工

Java多线程共享数据、同步、通信

一.线程共享数据 a)继承Thread,那么我们可以创建很多个这样的类,但是每个这样的类都是相互不关联的,也就是说我们Thread类中的内容每个创建出来的类都有一份,因此它不适合作为数据共享的线程来操作.同时由于Java继承的唯一性,我们只能继承一个对象. b)使用runnable就可以解决唯一性和不能共享的问题(不是说使用runnable就解决了共享问题,只是相对于创建Thread来说,它可以算的上是共享了,为了获得更精确的共享问题,它必须的使用线程同步操作).实现了runnable接口的类比

ava 同步-Java 多线程同步工具 CyclicBarrier

问题描述 Java 多线程同步工具 CyclicBarrier Java中使用CyclicBarrier控制多个线程在执行完后,才执行后续操作,请大家帮我分析下,项目两个代码中为什么执行结果不一样: 代码1. public class CyclicBarrierTest2 { public static void main(String[] args) throws InterruptedException, BrokenBarrierException { final CyclicBarrie

Java多线程同步问题的探究(三、Lock来了,大家都让开【1.认识重入锁】)

在上一节中,我们已经了解了Java多线程编程中常用的关键字synchronized,以及与之相关的对象锁机制.这一节中,让我们一起来认 识JDK 5中新引入的并发框架中的锁机制. 我想很多购买了<Java程序员面试宝典>之类图书的朋友一定对下面这个面试题感到非常熟悉: 问:请对比synchronized与java.util.concurrent.locks.Lock 的异同. 答案:主要相同点:Lock能完成synchronized所实现的所有功能 主要不同点:Lock有比synchroniz

Java多线程同步问题的探究(二、给我一把锁,我能创造一个规矩)

在上一篇中,我们讲到了多线程是如何处理共享资源的,以及保证他们对资源进行互斥访问所依赖的重要机制:对象锁. 本篇中,我们来看一看传统的同步实现方式以及这背后的原理. 很多人都知道,在Java多线程编程中,有一个重要的关键字,synchronized.但是很多人看到这个东西会感到困惑:"都说同步机制是 通过对象锁来实现的,但是这么一个关键字,我也看不出来Java程序锁住了哪个对象阿?" 没错,我一开始也是对这个问题感到困惑和不解.不过还好,我们有下面的这个例程: 1 public cla

Java多线程同步问题的探究(一、线程的先来后到)

众所周知,在Java多线程编程中,一个非常重要的方面就是线程的同步问题. 关于线程的同步,一般有以下解决方法: 1. 在需要同步的方法的方法签名中加入synchronized关键字. 2. 使用synchronized块对需要进行同步的代码段进行同步. 3. 使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象. 另外,为了解决多个线程对同一变量进行访问时可能发生的安全性问题,我们不仅可以采用同步机制,更可以通过JDK 1.2中加入的 ThreadLocal

Java多线程的同步示例及对象锁机制

java多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问. 下面以一个简单的实例来进行对比分析.实例要完成的工作非常简单,就是创建10个线程,每个线程都打印从0到99这100个数字,我们希望线程之间不会出现交叉乱序打印,而是顺序地打印. 先来看第一段代码,这里我们在run()方法中加入了synchronized关键字,希望能对run方法进行互斥访问,但结果并不如我们希望那样,这 是因为这里synchronized锁住的是this对象,即