juc包下四大并发工具

juc.CountDownLatch 闭锁

一个线程在等待一组线程后再恢复执行

await()等待其他线程执行完毕

被等待线程执行完毕后计数器-1

如何知道其他线程执行完了?

计数器,若一组线程为,CountDown为5,减到0代表等待线程被全部执行完毕

一次性工具:当Countdown的值减到0的时候再也无法恢复

juc内部的代码都是lock体系来实现的

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

// 运动员线程
class CDLTask implements Runnable {
    private CountDownLatch countDownLatch;

    public CDLTask(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"开始跑步");
        try {
            TimeUnit.SECONDS.sleep(1);
            System.out.println(Thread.currentThread().getName()+"到达终点");
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(4);
        CDLTask cdlTask = new CDLTask(countDownLatch);
        System.out.println("比赛开始...");
        new Thread(cdlTask,"运动员A").start();
        new Thread(cdlTask,"运动员B").start();
        new Thread(cdlTask,"运动员C").start();
        new Thread(cdlTask,"运动员D").start();
        // 等待所有线程都到达终点后再输出此语句
        countDownLatch.await();
        System.out.println("比赛结束...");
    }
}



juc.CyclicBarrier  循环栅栏

一组线程同时到达临界点后再恢复执行(先到达临界点的线程会阻塞,直到所有线程都到达临界点)

public CyclicBarrier(int parties, Runnable barrierAction)

当多个线程同时到达临界点时,

随机挑选一个线程执行barrierAction后再同时恢复执行

计数器的值可以恢复

await

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

class CBTask implements Runnable {
    private CyclicBarrier cyclicBarrier;

    public CBTask(CyclicBarrier cyclicBarrier) {
        this.cyclicBarrier = cyclicBarrier;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+
                "正在写入数据...");
        try {
            TimeUnit.SECONDS.sleep(2);
            System.out.println(Thread.currentThread().getName()+
                    "写入数据完毕,等待其他线程写入完毕...");
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println("所有线程均已写入完毕,继续恢复执行...");
    }
}
class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4
                ,() -> {
            System.out.println("当前线程为:"+Thread.currentThread().getName());
        });
        CBTask cbTask = new CBTask(cyclicBarrier);
        for (int i = 0; i < 4; i++) {
            new Thread(cbTask,"写线程"+(i+1)).start();
        }
    }
}


juc.Exchanger 线程交换器

用于两个线程直线的数据交换,当Exchanger只有一个线程时,该线程会阻塞直到有别的线程调用exchange进入缓冲区,当前线程与新线程交换数据后同时恢复执行。
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;

class ExchangerDemo {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<>();
        Thread girlThread = new Thread(() -> {
            try {
                String girl = exchanger.exchange("我喜欢你.....");
                System.out.println("女生说:"+girl);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        girlThread.start();
        Thread boyThread = new Thread(() -> {
            System.out.println("女神缓缓步入眼帘...");
            try {
                TimeUnit.SECONDS.sleep(1);
                String boy = exchanger.exchange("我喜欢你!");
                System.out.println("男生说:"+boy);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        boyThread.start();
    }
}


juc.Semaphore 信号量

acquire() : 尝试占用一个信号量,失败的线程会阻塞直到有新的信号量

release() : 释放一个信号量

acquire(int n) : 尝试占用n个信号量,失败的线程会阻塞直到有新的信号量

release(int n) : 释放n个信号量
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

class SemaphoreTask implements Runnable {
    private Semaphore semaphore;

    public SemaphoreTask(Semaphore semaphore) {
        this.semaphore = semaphore;
    }

    @Override
    public void run() {
        try {
            semaphore.acquire(2);
            System.out.println(Thread.currentThread()
                    .getName()+"占用2台设备生产");
            TimeUnit.SECONDS.sleep(2);
            System.out.println(Thread.currentThread()
                    .getName()+"生产完毕,释放设备");
            semaphore.release(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(5);
        SemaphoreTask task = new SemaphoreTask(semaphore);
        for (int i = 0; i < 8; i++) {
            new Thread(task,"工人"+(i+1)).start();
        }
    }
}

原文地址:https://www.cnblogs.com/hetaoyuan/p/11317029.html

时间: 2024-10-18 20:23:36

juc包下四大并发工具的相关文章

Java语言Lang包下常用的工具类介绍_java - JAVA

文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 无论你在开发哪中 Java 应用程序,都免不了要写很多工具类/工具函数.你可知道,有很多现成的工具类可用,并且代码质量都很不错,不用你写,不用你调试,只要你发现. 在 Apache Jakarta Common 中, Lang 这个 Java 工具包是所有 Apache Jakarta Common 项目中被使用最广泛的,几乎你所知道的名气比较大的软件里面都有用到它,包括 Tomcat, Weblogic, Webs

juc下的并发工具类和线程池

工具类 CountDownLatch 利用它可以实现类似计数器的功能.比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了. package com.yjc.juc; import java.util.concurrent.CountDownLatch; public class CountDownLatchDemo { public static void main(String[] args) throws Interrupt

Java线程与并发编程实践----并发工具类与Executor框架

java5之前,我们使用诸如synchronized,wait(),notify()方法对线程的操作属于对 底层线程的操作,这样会出现很多的问题: 低级的并发原语,比如synchronized,wait(),notify()经常难以正确使用.误用会导致 竞态条件,线程饿死,死锁等风险. 泰国依赖synchronized会影响程序性能以及程序的可扩展性 开发者经常需要高级线程结构,如线程池,信号量.java对底层线程的操作不包含这些结. 为解决这些问题,java5引入并发工具类,该工具类主要有下面

Java学习笔记—多线程(并发工具类,java.util.concurrent.atomic包)

在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程间交换数据的一种手段.本章会配合一些应用场景来介绍如何使用这些工具类. CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成操作.假如有这样一个需求:我们需要解析一个Excel里多个sheet的数据,此时可以考虑使用多线程,每个线程解析一个sheet里的数据,

java工具类 获取包下所有类

[java] view plaincopy package com.threeti.util; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; import java.uti

玩转Java并发工具,精通JUC,成为并发多面手

玩转Java并发工具,精通JUC,成为并发多面手 深度解密JUC库,提升五位一体的并发综合实力 使用场景+作用+底层原理逐一解读,吃透JUC并发包 掌握丰富的并发工具,解决实际问题,面试.工作轻松搞定 链接:https://pan.baidu.com/s/1ehvQUq9LUmmrZHYH7_DuGw 提取码:jyfs 全网程序学习资料,包含Java后端.前端.人工智能大数据.Python.数据结构和算法.运维.测试.面试相关等课程,所有视频资料均无加密,普通播放器就可播放,加客服微信coder

Linux下高并发socket最大连接数所受的各种限制(详解)

1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄).可使用ulimit命令查看系统允许当前用户进程打开的文件数限制: [[email protected] ~]$ ulimit -n1024 这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中

Java多线程之JUC包:ReentrantReadWriteLock源码学习笔记

若有不正之处请多多谅解,并欢迎批评指正. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/go2sea/p/5634701.html ReentrantLock提供了标准的互斥操作,但在应用中,我们对一个资源的访问有两种方式:读和写,读操作一般不会影响数据的一致性问题.但如果我们使用ReentrantLock,则在需要在读操作的时候也独占锁,这会导致并发效率大大降低.JUC包提供了读写锁ReentrantReadWriteLock,使得读写锁分离,在上述情

java.util.concurrent包下的几个常用类

1.Callable<V> Callable<V>与Runnable类似,理解Callable<V>可以从比较其与Runnable的区别开始: 1)从使用上:实现的Callable<V>的类需要实现call()方法,此方法有返回对象V:而Runnable的子类需要实现run()方法,但没有返回值: 2)如果直接调用Callable<V>的子类的call()方法,代码是同步顺序执行的:而Runnable的子类是线程,是代码异步执行. 3)将Call