CountDownLatch与CyclicBarrier与Semaphore比较并分析

CountDownLatch

概念

一种线程的辅助,允许一个操作等待直到某个或某组操作完成再执行

倒数,计数为0时执行

代码

demo1

package top.ygy.thread;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @Description: TODO(CountDownLatch测试)
 * @author yangguangyuan
 * @date 2019年5月31日
 *
 * 第一种用法:主线程执行完后,再执行其他线程
 *         主线程等待其他线程执行完,再执行主线程
 * 第二种用法:将一个任务分成多个任务,执行完成之后,在执行其他任务
 */
public class CountDownLatchDemo {

	public static void main(String[] args) {
		Driver driver = new Driver();
		try {
			driver.main();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

class Driver {
	void main() throws InterruptedException {
		int N = 3;
		CountDownLatch startSignal = new CountDownLatch(1);
		CountDownLatch doneSignal = new CountDownLatch(N);

		for (int i = 0; i < N; ++i) // create and start threads
			new Thread(new Worker(startSignal, doneSignal)).start();

		// doSomethingElse(); // don't let run yet
		
		System.out.println(1+"主线程执行任务,其他线程等待中");
		TimeUnit.MILLISECONDS.sleep(3000);
		System.out.println(1+"主线程执行完成,开始执行其他线程");
		//主线程准备完成,开始执行其他线程
		startSignal.countDown(); // let all threads proceed
		// doSomethingElse();

		System.out.println(2);
		doneSignal.await(); // wait for all to finish

		System.out.println("4");
	}
}

class Worker implements Runnable {
	private final CountDownLatch startSignal;
	private final CountDownLatch doneSignal;
	Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
		this.startSignal = startSignal;
		this.doneSignal = doneSignal;
	}
	public void run() {
		try {
			startSignal.await();
			doWork();
			doneSignal.countDown();
		} catch (InterruptedException ex) {
		}
	}

	void doWork() {
		try {
			TimeUnit.MILLISECONDS.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "");
		System.out.println(Thread.currentThread().getName() + "_3");
	}
}

demo2

package top.ygy.thread;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * @Description: TODO(CountDownLatch测试)
 * @author yangguangyuan
 * @date 2019年5月31日
 *
 *       第一种用法:主线程执行完后,再执行其他线程 
 *       第二种用法:主线程等待其他线程执行完,再执行主线程
 */
public class CountDownLatchDemo2 {

	public static void main(String[] args) {
		Driver2 driver = new Driver2();
		try {
			driver.main();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

class Driver2 { // ...
	void main() throws InterruptedException {
		int N = 3;
		CountDownLatch doneSignal = new CountDownLatch(N);
		Executor e = Executors.newFixedThreadPool(20);

		for (int i = 0; i < N; ++i) // create and start threads
			e.execute(new WorkerRunnable(doneSignal, i));

		doneSignal.await(); // wait for all to finish
	}
}

class WorkerRunnable implements Runnable {
	private final CountDownLatch doneSignal;
	private final int i;
	WorkerRunnable(CountDownLatch doneSignal, int i) {
		this.doneSignal = doneSignal;
		this.i = i;
	}
	public void run() {
		try {
			doWork(i);
			doneSignal.countDown();
		} catch (Exception ex) {
		} // return;
	}

	void doWork(int i) {
		System.out.println("测试"+i);
	}
}

CyclicBarrier

概念

一种线程的辅助,允许一个操作等待直到某个或某组操作完成再执行

正数,计数达到预期值时执行

代码

矩阵计算

package top.ygy.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;

/**
 * @Description: TODO(CyclicBarrier矩阵示例)
 * @author yangguangyuan
 * @date 2019年6月6日
 *
 */
public class CyclicBarrierDemo {

	public static void main(String[] args) {
		float[][] matrix = new float[3][3];
		int counter = 0;
		for (int row = 0; row < matrix.length; row++) {
			for (int col = 0; col < matrix[0].length; col++) {
				matrix[row][col] = counter++;
			}
		}

		dump(matrix);

		new Solver(matrix);

		dump(matrix);

	}

	static void dump(float[][] matrix) {
		for (int row = 0; row < matrix.length; row++) {
			for (int col = 0; col < matrix[0].length; col++) {
				System.out.println(matrix[row][col] + " ");
			}
		}
	}
}

class Solver {
	final int N;
	final float[][] data;
	final CyclicBarrier barrier;

	class Worker implements Runnable {
		int myRow;
		boolean done = false;
		Worker(int row) {
			myRow = row;
		}

		boolean done() {
			return done;
		}

		void processRow(int myRow) {
			System.out.println("Processing row: " + myRow);
			for (int i = 0; i < N; i++) {
				data[myRow][i] *= 10;
			}
			done = true;
		}

		public void run() {
			while (!done()) {
				processRow(myRow);

				try {
					barrier.await();
				} catch (Exception ex) {
					return;
				}
			}
		}
	}

	public Solver(float[][] matrix) {
		data = matrix;
		N = matrix.length;
		Runnable barrierAction = new Runnable() {
			public void run() {
				mergeRows();
			}
		};
		barrier = new CyclicBarrier(N, barrierAction);

		List<Thread> threads = new ArrayList<Thread>(N);
		for (int i = 0; i < N; i++) {
			Thread thread = new Thread(new Worker(i));
			threads.add(thread);
			thread.start();
		}

		waitUntilDone();
	}

	void mergeRows() {
		System.out.println("merging");
		synchronized ("abc") {
			"abc".notify();
		}
	}

	void waitUntilDone() {
		synchronized ("abc") {
			try {
				System.out.println("main thread waiting");
				"abc".wait();
				System.out.println("mian thread notified");
			} catch (Exception e) {
				System.out.println("main thread interrupted");
				e.printStackTrace();
			}
		}
	}
}

Semaphore

概念

一个计数信号量,信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制

(多个线程争抢多个资源)

代码

抢车位

package top.ygy.thread;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * @Description: TODO(抢车位示例)
 * @author yangguangyuan
 * @date 2019年6月19日
 *
 */
public class SemaphoreDemo {
	public static void main(String[] args) {
		Semaphore semaphore = new Semaphore(3);

		for (int i = 1; i <= 6; i++) {
			new Thread(() -> {
				try {
					semaphore.acquire();
					System.out.println(Thread.currentThread().getName()+"\t 抢到车位");
					TimeUnit.SECONDS.sleep(3);
					System.out.println(Thread.currentThread().getName()+"\t 停车3s后离开车位");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}finally {
					semaphore.release();
				}	
			},String.valueOf(i)).start();
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值