Java SDK 并发包全面总结(二)

简介: Java 并发包中的 Lock 和 Condition 主要解决的是线程的互斥和同步问题,这两者的配合使用,相当于 synchronized、wait()、notify() 的使用。

四、Semaphore


Semaphore 表示信号量,初始化对象的时候,需要传一个参数,表示信号量的计数器值。acquire() 方法将计数器加 1,release() 方法减 1,这两个方法都能够保证原子性。

信号量的简单示例:

public class SemaphoreTest {
    private final Semaphore semaphore = new Semaphore(1);
    private int value;
    public void addValue() {
        try {
            semaphore.acquire();
            value += 1;
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally {
            semaphore.release();
        }
    }

程序中使用信号量实现了一个线程安全的方法,初始值设为了 1,当多个方法访问 addValue 方法的时候,由于 acquire 方法保证原子性,所以只能有一个线程将计数器减 1 并进入临界区,另一个线程等待。

一个线程执行完后,调用 release 方法,计数器加 1,另一个等待的线程被唤醒。

Semaphore 与 Lock 的一个不同点便是信号量允许多个线程同时进入临界区,例如将初始值设置的更大一些。例如下面这个例子:

public class SemaphoreTest {
    //初始值 2,表示 2 个线程可同时进入临界区
    private final Semaphore semaphore = new Semaphore(2);
    public void test() {
        try {
            semaphore.acquire();
            System.out.println("线程" + Thread.currentThread().getName() + " 进入临界区 : " + System.currentTimeMillis());
            Thread.sleep(1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally {
            semaphore.release();
        }
    }
}

五、CountDownLatch


CountDownLatch 是一个线程同步的工具,主要实现一个线程等待多个线程的功能。在原始的 Thread 中,可以调用 join() 方法来等待线程执行完毕,而 CountDownLatch 则可以用在线程池中的线程等待。

下面是 CountDownLatch 的使用示例:

public class CountDownLatchTest {
    //实际生产中不推荐使用这种创建线程的方式
    private final ExecutorService threadPool = Executors.newFixedThreadPool(2);
    public void test() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(2);
        threadPool.execute(() -> {
            System.out.println("线程1执行完毕");
            latch.countDown();
        });
        threadPool.execute(() -> {
            System.out.println("线程2执行完毕");
            latch.countDown();
        });
        latch.await();
        System.out.println("两个线程都执行完毕");
        threadPool.shutdown();
    }
}

CountDownLatch 的初始值为 2,线程执行完毕则调用 countDown 方法,计数器减 1。减到 0 的时候,会唤醒主线程继续执行。


六、CyclicBarrier


CyclicBarrier 也是一个线程同步工具类,主要实现多个线程之间的互相等待。

CyclicBarrier 有两个构造函数,可以传一个计数器的初始值,还可以加上一个 Runnable,表示计数器执行减到 0 的时候,需要执行的回调方法。

public class CyclicBarrierTest {
    private final ExecutorService threadPool = Executors.newFixedThreadPool(2);
    private final CyclicBarrier barrier = new CyclicBarrier(2, this::note);
    public void print(){
        threadPool.execute(() -> {
            System.out.println("线程1执行完毕");
            try {
                barrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });
        threadPool.execute(() -> {
            System.out.println("线程2执行完毕");
            try {
                barrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });
        threadPool.shutdown();
    }
    public void note(){
        System.out.println("两个线程执行完毕");
    }
}

示例中设置 CyclicBarrier 的初始值为 2,线程执行完毕调用 await 方法,计数器减 1。print() 方法中的两个线程执行完后,计数器减到 0,就会调用 note 方法。

相关文章
|
3月前
|
Java Apache 开发工具
【Azure 事件中心】 org.slf4j.Logger 收集 Event Hub SDK(Java) 输出日志并以文件形式保存
【Azure 事件中心】 org.slf4j.Logger 收集 Event Hub SDK(Java) 输出日志并以文件形式保存
|
3月前
|
存储 Java API
【Azure 存储服务】Java Storage SDK 调用 uploadWithResponse 代码示例(询问ChatGTP得代码原型后人力验证)
【Azure 存储服务】Java Storage SDK 调用 uploadWithResponse 代码示例(询问ChatGTP得代码原型后人力验证)
|
3月前
|
Java 开发工具
通过Java SDK调用阿里云模型服务
在阿里云平台上,可以通过创建应用并使用模型服务完成特定任务,如生成文章内容。本示例展示了一段简化的Java代码,演示了如何调用阿里云模型服务生成关于“春秋战国经济与文化”的简短文章。示例代码通过设置系统角色为历史学家,并提出文章生成需求,最终处理并输出生成的文章内容。在实际部署前,请确保正确配置环境变量中的密钥和ID,并根据需要调整SDK导入语句及类名。更多详情和示例,请参考相关链接。
|
3月前
|
JSON Java API
【Azure API 管理】通过Java APIM SDK创建一个新的API,如何为Reqeust的Representation设置一个内容示例(Sample)?
【Azure API 管理】通过Java APIM SDK创建一个新的API,如何为Reqeust的Representation设置一个内容示例(Sample)?
|
3月前
|
存储 Java 开发工具
【Azure 存储服务】Java Azure Storage SDK V12使用Endpoint连接Blob Service遇见 The Azure Storage endpoint url is malformed
【Azure 存储服务】Java Azure Storage SDK V12使用Endpoint连接Blob Service遇见 The Azure Storage endpoint url is malformed
|
3月前
|
开发工具 数据安全/隐私保护
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
|
3月前
|
固态存储 Java 网络安全
【Azure Developer】使用Java SDK代码创建Azure VM (包含设置NSG,及添加数据磁盘SSD)
【Azure Developer】使用Java SDK代码创建Azure VM (包含设置NSG,及添加数据磁盘SSD)
|
机器学习/深度学习 编解码 Java
阿里云视觉智能开放平台(VIAPI)人脸美颜Java SDK使用说明
本文介绍人脸美颜FaceBeauty的语法及示例。
1412 0
阿里云视觉智能开放平台(VIAPI)人脸美颜Java SDK使用说明
|
Java 开发工具 计算机视觉
阿里云智能视觉生产图像处理人像分割Java SDK使用说明
人像分割用于识别输入图像中的人体轮廓,与背景进行分离,返回分割后的前景人像图(4通道),适用于单人、多人、复杂背景、各类人体姿态等场景。本文介绍如何使用阿里云智能视觉生产图像处理人体分割Java SDK,包括SDK的安装方法及SDK代码示例。
2875 1
|
自然语言处理 安全 Java
阿里云智能语音交互实时语音识别Java SDK使用说明
实时语音识别功能提供了对长时间的语音数据流进行识别,适用于会议演讲、视频直播等长时间不间断识别的场景。。本文介绍如何使用阿里云智能语音服务提供的Java SDK,包括SDK的安装方法及SDK代码示例。
3142 0