并发编程5-同步器

简介: <h2>Synchronizer</h2> <div>控制多个线程的流程,比如线程执行到某一个点的时候是等待还是通过。 JDK中自带了信号量,关卡,闭锁</div> <div><br></div> <h2>闭锁CoutDownLatch</h2> <div>达到最终状态前是关闭的,所有线程在此阻塞,  达到最终状态后开放,并且不可以再修改,所有线程进入可运行状态。</div> <

Synchronizer

控制多个线程的流程,比如线程执行到某一个点的时候是等待还是通过。 JDK中自带了信号量,关卡,闭锁

闭锁CoutDownLatch

达到最终状态前是关闭的,所有线程在此阻塞,  达到最终状态后开放,并且不可以再修改,所有线程进入可运行状态。
很适合,等待初始化, 等待依赖等等场景。
如:
/**
 * 设置countDownLatch的初始值,
 * 用await()来等待
 * 用countDown来倒计时 --初始值
 * 当初始值为0时await()等待被notify
 */
public class TestLatch {
    public static void main(String[] args) {
        final CountDownLatch latch = new CountDownLatch(1);
        final String[] datas = new String[3];
        new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("等待初始化");
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("初始化完成。开始执行");
                for (String data : datas) {
                    System.out.println(data);
                }
            }
        }.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        datas[0] = "我";
        datas[1] = "爱";
        datas[2] = "你";
        System.out.println("初始化完成");
        latch.countDown();
    }
}

信号量 

适用于连接池等场景
/**
 * 创建一个含有固定许可数的信号量
 * 线程用acquire()标记获得了一个许可,切许可-1,当许可为0时等待,
 * 用release来释放许可,许可+1,其他等待的线程可以获得许可了。
 */
public class TestSemaphore {
    public static void main(String[] args) {
        final Semaphore semaphore = new Semaphore(5);

        for (int i = 0; i < 20; i++) {
            new Thread("thread" + i){
                @Override
                public void run() {
                    try {
                        semaphore.acquire();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName() + "正在执行");
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    semaphore.release();;
                }
            }.start();
        }
    }
}

关卡

与闭锁不同的是,闭锁等待状态,而关卡是等待线程。
特别适用于把一个计算拆分成多个进行计算,最后再进行整合。
/**
 * 关卡
 * 定义所有线程都到关卡之后的行为及关卡中包含的线程数量
 *
 * 各个线程使用await方法来表示已经到这个关卡等着了
 *
 * 当指定数目的线程等着了,那么就开放关卡, 所有线程及刚才定义的行为都继续执行
 */
public class TestBarrier {
    public static void main(String[] args) {
        final String[] friends = new String[]{"1", "2", "3"};
        final CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
            @Override
            public void run() {
                System.out.println("出发");
            }
        });

        for (final String friend : friends) {
            new Thread(){
                @Override
                public void run() {
                    System.out.println(friend + "到集合点了");
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println(friend + "出发");
                }
            }.start();
        }
    }
}

打印如下:
1到集合点了
3到集合点了
2到集合点了
出发
2出发
3出发
1出发

相关文章
|
6月前
|
Java
JUC并发编程之等待唤醒机制
在JUC(Java Util Concurrent)并发编程中,线程等待唤醒机制是实现线程之间协作和同步的重要手段。这种机制允许一个线程挂起等待某个条件满足后被唤醒,以及另一个线程在满足某个条件后唤醒等待的线程。在Java中,有多种实现线程等待唤醒机制的方式,包括使用Object的wait()和notify()方法、Condition接口以及LockSupport类。
|
6月前
|
缓存 Java 编译器
JUC 并发编程之JMM
Java内存模型是Java虚拟机(JVM)规范中定义的一组规则,用于屏蔽各种硬件和操作系统的内存访问差异,保证多线程情况下程序的正确执行。Java内存模型规定了线程之间如何交互以及线程和内存之间的关系。它主要解决的问题是可见性、原子性和有序性。
|
4月前
|
Java
实现Java多线程中的线程间通信
实现Java多线程中的线程间通信
|
2月前
|
存储 Java
JAVA并发编程AQS原理剖析
很多小朋友面试时候,面试官考察并发编程部分,都会被问:说一下AQS原理。面对并发编程基础和面试经验,专栏采用通俗简洁无废话无八股文方式,已陆续梳理分享了《一文看懂全部锁机制》、《JUC包之CAS原理》、《volatile核心原理》、《synchronized全能王的原理》,希望可以帮到大家巩固相关核心技术原理。今天我们聊聊AQS....
|
5月前
|
存储 安全 Java
Java并发基础-线程间通信
Java并发基础-线程间通信
21 0
|
存储 设计模式 SpringCloudAlibaba
JUC并发编程(三):并发编程基石之AQS
**AQS: AbstractQueuedSynchronizer**,顾名思义,翻译过来叫**抽象队列同步器**,它是JUC并发编程的**基石**,定义了一套多线程访问共享资源的同步器框架,众多同步类底层都是基于AQS实现的,如常用的ReentrantLock、Semaphore、CountDownLatch等。
104 0
JUC并发编程(三):并发编程基石之AQS
|
Java
多线程和并发编程(3)—AQS和ReentrantLock实现的互斥锁
多线程和并发编程(3)—AQS和ReentrantLock实现的互斥锁
110 0
|
缓存 监控 安全
JUC并发编程之线程锁(一)
1.ReentrantLock(互斥锁)、2.ReentRantReaderWriterLock(互斥读写锁)、3.StampedLock(无障碍锁)、4.Condition(自定义锁)、5.LockSupport
75 0
【并发编程】线程间的通信
【并发编程】线程间的通信