java 并发控制

java并发控制使用场景是在多线程处理过程当中,如何实现线程之间数据处理的同步。 从jdk1.5之后,提供了两个工具: CyclicBarrier & CountDownlatch

CyclicBarrier

  • 原理
    CyclicBarrier 的作用官网给出的解释如下:
    A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.   
    CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. 
    The barrier is called cyclic because it can be re-used after the waiting threads are released. 
    
    说明: 作用在一组线程当中,使得一组线程能够达到某一个同样的状态
  • example
    • 代码
    public class CyclicBarrierTest {
    	public static void main(String[] args) throws InterruptedException {
    		// 初始化barrier 对应线程的个数
    		CyclicBarrier barrier = new CyclicBarrier(5);
    
    		// 初始化线程池
    		ExecutorService service = new ThreadPoolExecutor(10, 10,
    				100000, TimeUnit.DAYS, new LinkedBlockingQueue<>());
    
    		// 执行任务 todo something
    		service.execute(new RunTest(0, barrier));
    		service.execute(new RunTest(1, barrier));
    		service.execute(new RunTest(2, barrier));
    		service.execute(new RunTest(3, barrier));
    		service.execute(new RunTest(4, barrier));
    
    		// terminate executor service
    		service.awaitTermination(1000, TimeUnit.SECONDS);
    		service.shutdown(); // shutdown service
    	}
    
    	static class RunTest implements Runnable {
    		int no; // number
    		CyclicBarrier barrier;
    
    		public RunTest(int num, CyclicBarrier barrier) {
    			this.no = num;
    			this.barrier = barrier;
    		}
    
    		@Override
    			public void run() {
    				// do some work
    				System.err.println("NO. " + no + " is ready for running !!!");
    				try {
    					barrier.await();
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    					return;
    				} catch (BrokenBarrierException e) {
    					e.printStackTrace();
    					return;
    				}
    				System.err.println("NO. " + no + " running!!!!!");
    			}
    	}
    }
    
    • result
    NO. 0 is ready for running !!!
    NO. 1 is ready for running !!!
    NO. 2 is ready for running !!!
    NO. 3 is ready for running !!!
    NO. 4 is ready for running !!!
    NO. 0 running!!!!!
    NO. 4 running!!!!!
    NO. 1 running!!!!!
    NO. 2 running!!!!!
    NO. 3 running!!!!!
    
    • explanation
      由于存在barrier 所以参加任务的所有线程必须等待其余任何一个分配有任务的线程执行到指定的位置才能够继续往下执行,否则其余线程必须等待
      适用场景描述: await 之前的任务可以并行,之后也可以并行,但是中间有一个状态必须一致

CountDownLatch

  • 原理
    官网给出的解释如下:
    A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
    
    说明: 同步锁,具体来说对应同步计数器,等待一个或者多个线程完成
  • example
    • 代码
    public class CountDownLatchTest {
    	public static void main(String[] args) throws InterruptedException {
    		// 初始化barrier 对应线程的个数
    		CountDownLatch latch = new CountDownLatch(5);
    
    		// 初始化线程池
    		ExecutorService service = new ThreadPoolExecutor(10, 10,
    				100000, TimeUnit.DAYS, new LinkedBlockingQueue<>());
    
    		service.execute(new RunTaskTest(0, latch));
    		service.execute(new RunTaskTest(1, latch));
    		service.execute(new RunTaskTest(2, latch));
    		service.execute(new RunTaskTest(3, latch));
    		service.execute(new RunTaskTest(4, latch));
    
    		latch.await(); // 主线程等待所有任务
    		System.err.println("count down latch number " + latch.getCount());
    		service.shutdown(); // 关闭线程池
    	}
    
    	static class RunTaskTest implements Runnable {
    		int no; // number
    		CountDownLatch latch;
    
    		public RunTaskTest(int num, CountDownLatch latch) {
    			this.no = num;
    			this.latch = latch;
    		}
    
    		@Override
    			public void run() {
    				// do some work
    				System.err.println("NO. " + no + " is to count down");
    				latch.countDown(); // 计数器 - 1
    			}
    	}
    }
    
    • result
    NO. 0 is to count down
    NO. 1 is to count down
    NO. 2 is to count down
    NO. 3 is to count down
    NO. 4 is to count down
    count down latch number 0
    
    • explanation
      用于等待其余一个线程或者一组线程任务完成,其实也可以用作计数器 但是不能够increment 只能countDown

结论

CyclicBarrier 与 CountDownLatch 分别对应是等待一个线程还是一组线程完成,CyclicBarrier 是一组线程之间相互等待,而CountDownLatch 只是一个线程去等待其余线程完成的任务场景


你可能感兴趣的:(JAVA)