当前位置:首页 > 行业动态 > 正文

java信号量和countdownlatch怎么操作

Java中的信号量(Semaphore)和CountDownLatch是两种常用的同步工具,它们都可以用于控制多个线程之间的并发执行,本文将详细介绍这两种同步工具的使用方法。

信号量(Semaphore)

信号量是一个计数器,用于管理一组资源,它是一个整数变量,表示可用资源的数目,当一个线程需要使用资源时,它会尝试获取信号量,如果信号量的值大于0,那么线程就获得一个资源并继续执行;否则,线程将被阻塞,直到其他线程释放资源。

1、创建信号量

要创建一个信号量,可以使用java.util.concurrent.Semaphore类,构造函数接受一个整数参数,表示初始可用资源的数量。

import java.util.concurrent.Semaphore;
public class SemaphoreExample {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3); // 创建一个初始可用资源为3的信号量
    }
}

2、获取和释放资源

要获取一个资源,可以使用acquire()方法,这个方法会阻塞当前线程,直到信号量的值大于0。

semaphore.acquire(); // 获取一个资源

要释放一个资源,可以使用release()方法,这个方法会增加信号量的值。

semaphore.release(); // 释放一个资源

3、示例

下面是一个使用信号量的示例,它创建了两个线程,分别打印奇数和偶数,我们使用信号量来限制同时访问共享资源的线程数量。

import java.util.concurrent.Semaphore;
public class SemaphoreExample {
    public static void main(String[] args) throws InterruptedException {
        Semaphore semaphore = new Semaphore(1); // 创建一个初始可用资源为1的信号量
        Thread oddThread = new Thread(new PrintOddNumbers(semaphore));
        Thread evenThread = new Thread(new PrintEvenNumbers(semaphore));
        oddThread.start();
        evenThread.start();
        oddThread.join();
        evenThread.join();
    }
}
class PrintOddNumbers implements Runnable {
    private Semaphore semaphore;
    private int count = 1;
    public PrintOddNumbers(Semaphore semaphore) {
        this.semaphore = semaphore;
    }
    @Override
    public void run() {
        try {
            semaphore.acquire(); // 获取信号量,确保只有一个线程可以访问共享资源
            while (count <= 10) {
                System.out.println("奇数:" + count);
                count += 2;
                semaphore.release(); // 释放信号量,允许其他线程访问共享资源
                semaphore.acquire(); // 再次获取信号量,确保只有一个线程可以访问共享资源
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release(); // 最后释放信号量,确保所有线程都可以访问共享资源
        }
    }
}
class PrintEvenNumbers implements Runnable {
    private Semaphore semaphore;
    private int count = 2;
    public PrintEvenNumbers(Semaphore semaphore) {
        this.semaphore = semaphore;
    }
    @Override
    public void run() {
        try {
            semaphore.acquire(); // 获取信号量,确保只有一个线程可以访问共享资源
            while (count <= 10) {
                System.out.println("偶数:" + count);
                count += 2;
                semaphore.release(); // 释放信号量,允许其他线程访问共享资源
                semaphore.acquire(); // 再次获取信号量,确保只有一个线程可以访问共享资源
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release(); // 最后释放信号量,确保所有线程都可以访问共享资源
        }
    }
}

CountDownLatch(倒计时锁存器)

CountDownLatch是一个同步辅助类,它允许一个或多个线程等待其他线程完成操作,它的主要方法是countDown()和await()。countDown()方法用于减少倒计时锁存器的计数值,而await()方法用于等待倒计时锁存器的计数值为0,当计数值为0时,所有等待的线程将被唤醒,倒计时锁存器的计数值只能被初始化一次,且之后不能被重置,如果需要重置计数值,可以创建一个新的倒计时锁存器对象。

1、创建CountDownLatch对象:CountDownLatch(int count),其中count是倒计时锁存器的初始计数值,创建一个初始计数值为3的倒计时锁存器:CountDownLatch countDownLatch = new CountDownLatch(3);。

0