Java并发-同步器Semaphore,CountDownLatch


Java concurrent包中有提供多种同步器,此处模拟其中之二:信号量(Semaphore)和计数栓(CountDownLatch)


一、 Semaphore同步器

特征:

1. 经典的信号量,通过计数器控制对共享资源的访问

2. Semaphore(int count):创建拥有count个许可证的信号量

3.acquire()/acquire(int num) : 获取1/num个许可证

4. release/release(int num) : 释放1/num个许可证 


用以下代码模拟该编程模型!

package com.concurrent.src;

import java.util.concurrent.Semaphore;

/**
 * 信号量编程模型(三个客户去柜台办事,只初始化两个窗口,当有窗口闲下来才能为第三个客户服务)
 * @author admin
 *
 */
public class Ademo {

	public static void main(String[] args) {
		
		// 初始化两个银行柜员(窗口)
		Semaphore semaphore = new Semaphore(2);
		
		// 有A,B,C三个客户
		Person p1 = new Person(semaphore,"A");
		p1.start();
		
		Person p2 = new Person(semaphore,"B");
		p2.start();
		
		Person p3 = new Person(semaphore,"C");
		p3.start();
	}
}

class Person extends Thread {
	private Semaphore semaphore;
	
	public Person(Semaphore semaphore,String name) {
		setName(name);
		this.semaphore = semaphore;
	}
	
	@Override
	public void run() {
		System.out.println(getName() + " is waiting....");
		try {
			// 获取许可证
			semaphore.acquire();
			System.out.println(getName() + " is servicing ....");
			// 休眠一秒
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(getName() + " is done!");
		// 释放信号量
		semaphore.release();
	}
}


执行结果:

B is waiting....
B is servicing ....
A is waiting....
A is servicing ....
C is waiting....
B is done!
C is servicing ....
A is done!
C is done!

二、 CountDownLatch同步器

特征:

1. 必须发生指定数量的事件后才可以继续运行(比如赛跑比赛,裁判喊出3,2,1之后大家才同时跑)

2. CountDownLatch(int count):必须发生count个数量才可以打开锁存器

3. await:等待锁存器

4. countDown:触发事件


以下为计数栓编程模型:

package com.concurrent.src;

import java.util.concurrent.CountDownLatch;

/**
 * 数三个数同时起跑
 * @author admin
 *
 */
public class Bdemo {
	public static void main(String[] args) {
		// 创建一个计算栓,数三个数
		CountDownLatch countDownLatch = new CountDownLatch(3);
		// 有A,B,C个运动员
		new Racer(countDownLatch, "A").start();
		new Racer(countDownLatch, "B").start();
		new Racer(countDownLatch, "C").start();
		
		// 倒计时
		for (int i = 0; i < 3; i++) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(3-i);
			// 倒计时触发事件 -1
			countDownLatch.countDown();
			
			if(i == 2) {
				System.out.println("start.....");
			}
		}
	}
}

class Racer extends Thread {
	private CountDownLatch countDownLatch;
	
	public Racer(CountDownLatch countDownLatch,String name) {
		setName(name);
		this.countDownLatch = countDownLatch;
	}
	
	@Override
	public void run() {
		System.out.println(getName() + " is waiting....");
		try {
			// 等待锁存器
			countDownLatch.await();;
			for (int i = 0; i < 3; i++) {
				System.out.println(getName() + " : " + i);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

执行结果:

A is waiting....
C is waiting....
B is waiting....
3
2
1
start.....
A : 0
A : 1
A : 2
C : 0
C : 1
C : 2
B : 0
B : 1
B : 2






你可能感兴趣的:(Java,并发编程,多线程)