记录juc(高并发使用的工具)几个常用类的简单实用方法(java.util.concurrent)Phaser Semaphore CyclicWorker CountDownLatch

目录

 

Phaser 

Semaphore 

CyclicWorker 

CountDownLatch 


Phaser 

类似于旅行团集合后到景点旅游


import java.util.Random;
import java.util.concurrent.Phaser;

public class Lesson5_6 {
    public static void main(String[] args) throws InterruptedException {
        Phaser phaser = new MyPhaser();
        
        //登记有几个人
        PhaserWorker[] phaserWorkers = new PhaserWorker[10];
        for (int i = 0; i < phaserWorkers.length; i++) {
            phaserWorkers[i] = new PhaserWorker(phaser);
            // 注册 Phaser 等待的线程数,执行一次等待线程数 +1
            int register = phaser.register();
            System.out.println("登记:"+i);
//            register = phaser.arrive();
//            System.out.println("register:"+register);
        }
        
        //创造旅客,多于登记个数报异常,继续执行,并抛弃多于的那一个,少于登记个数,会一直阻塞
        for (int i = 0; i < phaserWorkers.length; i++) {
        	// 执行任务
        	new Thread(new PhaserWorker(phaser)).start();
        	System.out.println("create");
        }
        
    }
    static class PhaserWorker implements Runnable {
        private final Phaser phaser;
        public PhaserWorker(Phaser phaser) {
            this.phaser = phaser;
        }
        @Override
        public void run() {
        	
        	//表示所有线程暂停在这一步,等到所有线程都到了(10个)再继续向下(多于10,报异常,并抛弃多于的那个,少于10个,会一直阻塞在这里)
        	int login = phaser.arriveAndAwaitAdvance(); 
            System.out.println(Thread.currentThread().getName() + " | 到达::景点"+ login  );
            try {
                Thread.sleep(new Random().nextInt(5) * 1000);
                login = phaser.arriveAndAwaitAdvance();
                System.out.println(Thread.currentThread().getName() + " | 到达 ::景点"+login );
                //phaser.arriveAndAwaitAdvance(); // 景点 1 集合完毕发车
                Thread.sleep(new Random().nextInt(5) * 1000);
                login = phaser.arriveAndAwaitAdvance();
                System.out.println(Thread.currentThread().getName() + " | 到达::景点"+login  );
                //phaser.arriveAndAwaitAdvance(); // 景点 2 集合完毕发车
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    // Phaser 每个阶段完成之后的事件通知
    static class MyPhaser extends  Phaser{
        @Override
        protected boolean onAdvance(int phase, int registeredParties) { // 每个阶段执行完之后的回调
            switch (phase) {
                case 0:
                    System.out.println("==== 集合完毕发车 ====");
                    return false;
                case 1:
                    System.out.println("==== 景点1集合完毕,发车去下一个景点 ====");
                    return false;
                case 2:
                    System.out.println("==== 景点2集合完毕,发车回家 ====");
                    return false;
                default:
                    return true;
            }
        }
    }
}

 

Semaphore 

类似于车库里面车位,本例车位5个,车有十个,每辆车出库时间随机



import java.time.LocalDateTime;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class semaphore {
	
	public static void main(String[] args) {
		
		//相当于车位,本例5个
		Semaphore semaphore = new Semaphore(5);
		ThreadPoolExecutor semaphoreThread = new ThreadPoolExecutor(10, 50, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
		for (int i = 0; i < 10; i++) {
		    semaphoreThread.execute(() -> {
		        try {
		            // 堵塞获取许可,车子入库
		            semaphore.acquire();
		            System.out.println("Thread:" + Thread.currentThread().getName() + " 时间:" + LocalDateTime.now());
		            long time = 1000L*(new Random().nextInt(7)+3);
		            TimeUnit.SECONDS.sleep(time/1000);
		            // 释放许可,车子出库
		            semaphore.release();
		            
		            //队列长度表示未入库车辆个数
		            int length = semaphore.getQueueLength();
		            System.out.println("队列长度"+length);
		            TimeUnit.SECONDS.sleep(2);

		        } catch (InterruptedException e) {
		            e.printStackTrace();
		        }
		    });
		}
	}

}

CyclicWorker 

类似于大巴车,一次只运送一定数量乘客


import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class CyclicBarrierTest {
    public static void main(String[] args) throws InterruptedException {
    	
    	AtomicInteger count = new AtomicInteger();
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4, new Runnable() {
            @Override
            public void run() {
                System.out.println("发车了,当前车次:"+count.getAndIncrement());
                  //System.out.println("首位乘客:"+Thread.currentThread().getName());
            }
        });
        //一共10个乘客,只拉两次
        System.out.println("全部乘客:");
        for (int i = 0; i < 20; i++) {
            new Thread(new CyclicWorker(cyclicBarrier)).start();
        }
    }
    static class CyclicWorker implements Runnable {
        private CyclicBarrier cyclicBarrier;
        CyclicWorker(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
        @Override
        public void run() {
                long time = 1000L*(new Random().nextInt(7)+3);
                System.out.println("当前乘客:"+Thread.currentThread().getName());
                try {
                	Thread.sleep(time);
                	//等待,执行一次表示出现一名乘客
                    cyclicBarrier.await();
                    System.out.println("上车乘客:"+Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
        }
    }
}

 

CountDownLatch 

相当于医院患者早到排队,医生诊治的模型



import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class JUC {

	public static void main(String[] args) throws InterruptedException {
		
		// 医院闭锁
		CountDownLatch hospitalLatch = new CountDownLatch(1);
		int patient = 10;
		// 患者闭锁
		CountDownLatch patientLatch = new CountDownLatch(patient);
		System.out.println("患者排队");
		//此处采用缓存线程池,表示医院医生很多,能满足一对一体检,此处有patient个人排队
		ExecutorService executorService = Executors.newCachedThreadPool();
		for (int i = 0; i < patient; i++) {
		    final int j = i;
		    executorService.execute(() -> {
		    	long time = 1000L*(new Random().nextInt(10)+1);
		        try {
		        	//表示可以开始接受另外一个队列
		        	//当计数器不为 0 时,则调用该方法的线程阻塞,当计数器为 0 时,可以唤醒等待的一个或者全部线程
		        	//(此处现在是0,即可以唤起10个线程)
		        	hospitalLatch.await();
		            Thread.sleep(time);
		        } catch (InterruptedException e) {
		            e.printStackTrace();
		        }
		        System.out.println(Thread.currentThread().getName()+"  体检:" + j+" 耗时:"+time/1000);
		        patientLatch.countDown();
		    });
		}
		System.out.println("医生上班");
		
		hospitalLatch.countDown();
		//表示患者队列不再增加
		//当计数器不为 0 时,则调用该方法的线程阻塞,当计数器为 0 时,可以唤醒等待的一个或者全部线程
    	//此处现在不是0,即此方法的线程阻塞,一直到patientLatch.countDown()降低到0为止
		patientLatch.await();
		//程序阻塞结束,开始执行下一步
		System.out.println("医生下班");
		executorService.shutdown();
	}
}

 

 

你可能感兴趣的:(记录juc(高并发使用的工具)几个常用类的简单实用方法(java.util.concurrent)Phaser Semaphore CyclicWorker CountDownLatch)