跳到主要内容
  1. 所有文章/
  2. Java并发编程笔记/

JUC工具类(加法减法计数器)

·📄 961 字·🍵 2 分钟

CountDownLatch(类似减法计数器) #

文档介绍: 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

image-20220209130501510.png

import java.util.concurrent.CountDownLatch;

public class Main{
    public static void main(String[] args) throws InterruptedException {
        // 总数是6
        CountDownLatch countDownLatch = new CountDownLatch(6);

        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "==> Go Out");
                countDownLatch.countDown(); // 每个线程都数量 -1
            },String.valueOf(i)).start();
        }
        countDownLatch.await(); // 等待计数器归零 然后向下执行
        System.out.println("close door");
    }
}
/**
1==> Go Out
2==> Go Out
5==> Go Out
4==> Go Out
3==> Go Out
6==> Go Out
close door
**/

主要方法:

  • countDown 减一操作;
  • await 等待计数器归零

await 等待计数器归零,就唤醒,再继续向下运行

CyclickBarrier(类似加法计数器) #

文档介绍:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。

image-20220209130830579.png

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

public class Main {
    public static void main(String[] args) {
        // 主线程
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7,() -> {
            System.out.println("召唤神龙");
        });

        for (int i = 1; i <= 7; i++) {
            // 子线程
            int finalI = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "收集了第" + finalI + "颗龙珠");
                try {
                    cyclicBarrier.await(); // 加法计数 等待
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
/**
Thread-1收集了第2颗龙珠
Thread-0收集了第1颗龙珠
Thread-2收集了第3颗龙珠
Thread-3收集了第4颗龙珠
Thread-4收集了第5颗龙珠
Thread-5收集了第6颗龙珠
Thread-6收集了第7颗龙珠
召唤神龙
**/

Semaphore(计数信号量) #

文档介绍:一个计数信号量。

image-20220209131720042.png

public class SemaphoreDemo {
    public static void main(String[] args) {

        // 线程数量,停车位,限流
        Semaphore semaphore = new Semaphore(3);
        for (int i = 0; i <= 6; i++) {
            new Thread(() -> {
                // acquire() 得到
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "抢到车位");
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName() + "离开车位");
                }catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release(); // release() 释放
                }
            }).start();
        }
    }
}

/**
Thread-1抢到车位
Thread-0抢到车位
Thread-2抢到车位
Thread-0离开车位
Thread-2离开车位
Thread-1离开车位
Thread-5抢到车位
Thread-3抢到车位
Thread-4抢到车位
Thread-5离开车位
Thread-3离开车位
Thread-6抢到车位
Thread-4离开车位
Thread-6离开车位
**/

原理:

semaphore.acquire()获得资源,如果资源已经使用完了,就等待资源释放后再进行使用!

semaphore.release()释放,会将当前的信号量释放+1,然后唤醒等待的线程!

作用: 多个共享资源互斥的使用! 并发限流,控制最大的线程数!