Multithreading tools CountDownLatch, CyclicBarrier, Semaphore

Multithreading tools CountDownLatch, CyclicBarrier, Semaphore

CountDownLatch and functions much like CyclicBarrier,

Let me talk about the difference between them now, in my opinion on two points,

1, CountDownLatch similar to the down counter, CyclicBarrier similar counter adder

2, CountDownLatch the configuration from the time the counter value has reached 0 the initial injection, not reset, CyclicBarrier counter has an initial value to, but is CyclicBarrier addition, when added to the initial value, the reset to zero.

A, CountDownLatch

 * Multithreaded tools java.util.concurrent package under
 * a CountDownLatch similar to a counter, a synchronization tools, coordinate the synchronization between multiple threads
 * Features: subtraction calculation, when the count is 0, the blocking wakeup thread
 * usage scenarios: requires special thread before execution of the main thread
 * disadvantage of CountDownLatch: CountDownLatch in configuration from the time counter value has reached 0 the initial injection, is not reset, CyclicBarrier do not want to be reused.

Example: Before performing the main thread, we need to run 50 sub-thread

public class MyCountDownLatch {
    public static final int COUNTDOWNLATCHCOUNT = 50;
    public static int i = 0;
    static Lock lock = new ReentrantLock();
    public static void inadd(){
        lock.lock();
        try{
            i++;
        }finally {
            lock.unlock();
        }
    }
	public static void main(String[] args) {
		
			long startTime = System.currentTimeMillis();
			try {
				ExecutorService executorService = Executors.newFixedThreadPool(20);
				CountDownLatch countDownLatch = new CountDownLatch(COUNTDOWNLATCHCOUNT);
				for (int i = 0; i < COUNTDOWNLATCHCOUNT; i++) {
					//初始化计数器的值
					executorService.execute(new MyCountDownLatchThread(countDownLatch,i));
				}
				countDownLatch.await();
				executorService.shutdown();
				long endTime = System.currentTimeMillis();
				System.out.println("---执行主线程---,执行其他线程耗时"+(double)(endTime-startTime)/1000+"秒");
				System.out.println("--执行线程数:"+i);

			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
				
	}
	private static class MyCountDownLatchThread implements Runnable{
        private CountDownLatch latch;
        private int flag;
		
		public MyCountDownLatchThread(CountDownLatch latch, int flag) {
			super();
			this.latch = latch;
			this.flag = flag;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			synchronized (this) {
				try {
					Random random = new Random();
					int randomNum = random.nextInt((3000 - 1000)+1)+1000;//制造1000到3000之间的随机数
					Thread.sleep(randomNum);
					System.out.println("线程"+flag+"已执行完毕,耗时"+(double)randomNum/1000+"秒");
					inadd();
					latch.countDown(); 
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}

}

Execution effect:

二、CyclicBarrier

 * Multithreaded tools java.util.concurrent package under
 * a CyclicBarrier barrier means is generally reusable
 * Characteristics: counting mode, the release of all waiting threads count reaches the predetermined value, the count is reset to 0 and restarts
 * : meaning set number blocking barrier method configured by n, the await call () method of count by one, if the value is not equal to 1 plus constructor method
 when n * value, the thread is blocked, the value reaches n. Release all waiting threads, re-count value is 0, and so on.
 * Advantages: Reusable

Examples: interviewing, there are three stages (early face, two faces on three sides), a total of four people to interview, regulations require the company to face the beginning of the end of the two faces on three sides, to achieve:

public class MyCyclicBarrier {
	public static final int MS_COUNT = 3; //面试环节数量
	//关键点:阻塞数等于面试人员数量,以每个人员为一个线程,每次面试,只有所有人都面过的时候,
	//阻塞放开,执行下次面试。
	public static final int PERSIONCOUNT = 4; //面试人员的数量
	public static final int ZS_COUNT = 4; //阻塞数
	
   	public static void main(String[] args) {		
		try {
			
			ExecutorService executorService = Executors.newFixedThreadPool(10);
			CyclicBarrier cyclicBarrier = new CyclicBarrier(ZS_COUNT);
		    for (int i = 0; i < PERSIONCOUNT; i++) {
		    	executorService.execute(new MyCyclicBarrierThread(cyclicBarrier,i));
			}
		    executorService.shutdown();
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

	}
	
	private static class MyCyclicBarrierThread implements Runnable{
        private CyclicBarrier cer;
        private int persionName;
        
		public MyCyclicBarrierThread(CyclicBarrier cer, int persionName) {
			super();
			this.cer = cer;
			this.persionName = persionName;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			synchronized (this) {
				for (int i = 0; i < MS_COUNT; i++) {
					Random random = new Random();
					int randomNum = random.nextInt((3000 - 1000)+1)+1000;//制造1000到3000之间的随机数
					try {
						Thread.sleep(randomNum);
						switch (i) {
						case 0:
							System.out.println("人员"+persionName+"已通过初面,耗时"+(double)randomNum/1000+"天");
							break;
						case 1:
							System.out.println("人员"+persionName+"已通过二面,耗时"+(double)randomNum/1000+"天");
							break;
						case 2:
							System.out.println("人员"+persionName+"已通过三面,耗时"+(double)randomNum/1000+"天");
							break;							
						default:
							break;
						}
						this.cer.await();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (BrokenBarrierException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
		
	}
}

To achieve the effect of:

Here is the place to emphasize:

Obstructive number equal to the number of interviews, the purpose is to each person as a thread, each interview, only when all over the surface,
blocking release, the implementation of the next interview.

Otherwise: When the blocked number is less than the number of interviewers, the effect of:

The results achieved problems.

When the blocked number greater than the number of interviews, the effect of:

The reason is in the for loop, await () to add the count has not reached the barrier CyclicBarrier, the thread will not let go, would have been blocked

三、Semaphore

 * Semaphore translated literally as semaphores, Semaphore can control the number of threads simultaneously access, () obtained by Acquire
 * a license, if not wait, and release () Releases a permit.

Semaphore class java.util.concurrent located under the package, which provides two constructors:

public Semaphore(int permits) {          //参数permits表示许可数目,即同时可以允许多少线程进行访问
    sync = new NonfairSync(permits);
}
public Semaphore(int permits, boolean fair) {    //这个多了一个参数fair表示是否是公平的,即等待时间越久的越先获取许可
    sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
}

acquire (), release () method:

public void acquire() throws InterruptedException {  }     //获取一个许可
public void acquire(int permits) throws InterruptedException { }    //获取permits个许可
public void release() { }          //释放一个许可
public void release(int permits) { }    //释放permits个许可

 注意:

acquire()用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可。

release()用来释放许可。注意,在释放许可之前,必须先获获得许可。

立即得到执行结果的方法:

public boolean tryAcquire() { };    //尝试获取一个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException { };  //尝试获取一个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false
public boolean tryAcquire(int permits) { }; //尝试获取permits个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException { }; //尝试获取permits个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false

例子:图书馆有3本书,但有5名学生预约,一本书只能由一名学术使用,只有使用完了其他人才能使用。

public class MySemaphore {

	public static final int BOOKCOUNT = 3; 
	public static final int STUDENTCOUNT = 5;
	public static void main(String[] args) {		
		ExecutorService executorService = Executors.newFixedThreadPool(10);
		Semaphore semaphore = new Semaphore(BOOKCOUNT); //书本数目
		for (int i = 0; i < STUDENTCOUNT; i++) {
	    	executorService.execute(new MySemaphoreThread(semaphore,i));
		}
	    executorService.shutdown();
	}
	private static class MySemaphoreThread implements Runnable{
        private Semaphore semaphore;
        private int num;
        
		public MySemaphoreThread(Semaphore semaphore, int num) {
			super();
			this.semaphore = semaphore;
			this.num = num;
		}
		@Override
		public void run() {
			// TODO Auto-generated method stub
			synchronized (this) {
				try {
					this.semaphore.acquire();
					System.out.println("学术"+num+"借出一个书本");
					Random random = new Random();
					int randomNum = random.nextInt((3000 - 1000)+1)+1000;//制造1000到3000之间的随机数
					Thread.sleep(randomNum);
					System.out.println("学术"+num+"还回一个书本");
					this.semaphore.release();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
}

效果:

 

发布了95 篇原创文章 · 获赞 180 · 访问量 4万+

Guess you like

Origin blog.csdn.net/weixin_38316697/article/details/89364515