JAVA high concurrency (JUC) use of JUC tools

Not much to say, just go to the code: the
first tool class CountDownLatch:
CountDownLatch: CountDownLatch mainly has two methods, when one or more threads call the await method, the writing thread will block. When other threads call the CountDownLatch method, the counter will be decremented by 1 (the thread calling the CountDownLatch method will not be blocked). When the value of the counter becomes 0, the thread blocked by the await method will be awakened and continue execution.
Let’s take an example for comparison: 10 people all get out of the door and then lock the door.


    public static void main(String[] args) {
     		        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "出来了");
            }, String.valueOf(i)).start();
        }
        System.out.println("锁门");   
    }        
//        0出来了
//        锁门
//        3出来了
//        2出来了
//        1出来了
//        5出来了
//        6出来了
//        4出来了
//        8出来了
//        7出来了
//        9出来了

Obviously we can't do it. How can we be sure that the door is locked when all 10 people come out?
At this time, we can use our first tool class CountDownLatch
code as follows:

CountDownLatch countDownLatch = new CountDownLatch(10);
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "出来了");
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();  //减到0才继续
        System.out.println("锁门");
        
//        0出来了
//        3出来了
//        1出来了
//        2出来了
//        4出来了
//        5出来了
//        7出来了
//        6出来了
//        8出来了
//        9出来了
//        锁门

If it is not reduced to 0, it will always be blocked here!

The second tool class CyclicBarrier:
CyclicBarrier is similar to the first one, we can look at its constructor:

CyclicBarrier(int parties, Runnable barrierAction) 
创建一个新的 CyclicBarrier ,当给定数量的线程(线程)等待时,它将跳闸,当屏障跳闸时执行给定的屏障动作,由最后一个进入屏障的线程执行。

Next on the code.

    public static void main(String[] args) {
         CyclicBarrier cyclicBarrier = new CyclicBarrier(10, () -> {
            System.out.println("锁门");
        });
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "第" + finalI + "出门");
                try {
                    cyclicBarrier.await();
                    System.out.println(finalI);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
    }

The result is as follows:
Insert picture description here
We can find that all threads are blocked here by the await() method. When a given number of threads (threads) are waiting, it will trip. When the barrier trips, the given barrier action will be executed, and the last one will enter. Thread execution of the barrier.

The third tool class Semaphore:
Imagine a scene of grabbing parking spaces. If there are 3 or 6 parking spaces, the code is as follows:

public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore= new Semaphore(3);//模拟资源类,有3个空车位  为1的时候相当于synchronized
        for(int i=0;i<6;i++){
            new Thread(()->{
                try {
                    semaphore.acquire(); //占用
                    System.out.println(Thread.currentThread().getName()+"\t抢占到了车位");
                    Thread.sleep(3000);
                    System.out.println(Thread.currentThread().getName()+"\t离开了车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();//交还车位
                }
            },String.valueOf(i)).start();
        }
    }
}

The execution results are as follows:
Insert picture description here
We define two operations on the semaphore:

  • acquire (acquisition) When a thread calls the acquire operation, it must successfully acquire the semaphore (the semaphore minus 1), or wait until it knows that a thread
    releases the semaphore, or wakes up
  • The release actually adds 1 to the value of the semaphore and then wakes up the waiting thread.
    Semaphores are mainly used for two purposes, one is suitable for mutually exclusive use of multiple shared resources, and the other is suitable for control of the number of concurrent threads

Guess you like

Origin blog.csdn.net/Pzzzz_wwy/article/details/106127741