`
learnworld
  • 浏览: 168344 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

j.u.c同步器使用总结

    博客分类:
  • java
阅读更多
        从jdk1.5开始,java.util.concurrent提供了在并发编程中很常用的实用工具类,包括几个小的、已标准化的可扩展框架,以及一些提供有用功能的类。没有这些类,并发功能会很难实现或实现起来冗长乏味。本文将关注j.u.c中提供的四种同步器: CountDownLatch, CyclicBarrier, Semaphore, Exchanger,它们用于辅助实现一些常见的同步场景。下面将分别介绍java并发包中的每种同步器使用方法和常见场景。

一、CountDownLatch
1. 功能
用于同步多个线程的完成操作,让先完成的线程进行等待,直至所有线程完成。

2. 使用方法
1)新建CountDownLatch对象,定义总计数器latch。
2)调用await()方法,使当前线程进入等待状态。
3)调用countDown()方法,使计数器减一,当计数器降为0时,线程重新恢复运行。

3. 示例
场景: 10个同事约好周末一起去西湖游玩,先在公司集合完毕,到齐后一起出发,每人骑一辆自行车,统一在西湖集合。
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class CountDownLatchTest {
	
	public static void main(String[] args) {
		final CountDownLatch start = new CountDownLatch(1);
		final CountDownLatch done = new CountDownLatch(10);
		ExecutorService executor = Executors.newFixedThreadPool(10);
		for(int i = 0; i<10; i++){
			executor.execute(new Employee(start, done));
		}
		
		start.countDown();
		System.out.println("大部队已经准备出发.");
		try {
			done.await();
		} catch (InterruptedException e) {
			
		}
		System.out.println("大部队在西湖集结完毕.");
		executor.shutdown();

	}
}

class Employee implements Runnable {
	private CountDownLatch start;
	private CountDownLatch done;
	
	public Employee(CountDownLatch start, CountDownLatch done){
		this.start = start;
		this.done = done;
	}
	
	@Override
	public void run() {		
		//到公司后等待
		try {
			start.await();
		} catch (InterruptedException e) {
			
		}
		
		System.out.println(Thread.currentThread() + "从公司出发,去西湖路上.");
		try {
			Thread.sleep(new Random().nextInt(5000));
		} catch (InterruptedException e1) {
		}
		
		//哥已经先到了
		done.countDown();
	}
	
}



二、CyclicBarrier
1. 功能
类似CountDownLatch,用于多次的同步多个线程的完成操作。

2. 使用方法
1)新建CyclicBarrier对象,定义总计数器和结束后的下一步动作。
2)调用await()方法,使当前线程进入等待;当await()方法的调用次数达到总计数器时,各等待线程恢复运行。

3. 示例
场景: 再考虑上面提到的场景,10个同事约好周末一起去西湖游玩,先在公司集合完毕;每人骑一辆自行车,在西湖集合完毕;大家再分散活动,中午在苏堤集合,一起吃午饭。如果采用CountDownLatch,需要定义三个CountDownLatch,下面演示如何使用CyclicBarrier解决这类问题。
import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class CyclicBarrierTest {

	public static void main(String[] args) {
		final CyclicBarrier barrier = new CyclicBarrier(10, new Runnable(){
			@Override
			public void run() {
				System.out.println("大部队集合完毕了。");				
			}
			
		});
		
		ExecutorService executor = Executors.newFixedThreadPool(10);
		for(int i = 0; i<10; i++){
			final int num = i;
			executor.execute(new Runnable(){
				@Override
				public void run() {
					System.out.println("num: " + num + " 从公司出发了.");
					try {
						Thread.sleep(new Random().nextInt(5000));
						barrier.await(); // 在西湖等待大部队
					
						System.out.println("num: " + num + " 在西湖开始游玩.");
						
						Thread.sleep(new Random().nextInt(5000));
						barrier.await(); //等待大部队就餐
					} catch (Exception e1) {
					}					
				}				
			});
		}

		executor.shutdown();
	}
}



三、Semaphore 
1. 功能
一个计数信号量,用于限制可以访问某些资源的线程数目。

2. 使用方法
1)新建Semaphore对象,定义资源数目。
2)线程通过acquire()获取资源,通过release()释放资源。

3. 示例
场景: 10个同事一起去游戏机厅打游戏,但游戏机厅只有四台游戏机,下面示例说明使用Semaphore限制同时玩游戏机的同事数目。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;


public class SemaphoreTest {

	public static void main(String[] args) {
		final Semaphore semaphore = new Semaphore(2,true);
		
		ExecutorService executor = Executors.newFixedThreadPool(10);
		for(int i = 0; i<10; i++){
			final int num = i;
			executor.execute(new Runnable(){
				@Override
				public void run() {
					System.out.println("num: " + num + " 想要打游戏. 还有" + semaphore.availablePermits() + "台游戏机.");
					try {
						semaphore.acquire(1);
					} catch (InterruptedException e) {
						
					}
					System.out.println("num: " + num + " 开始打游戏. 还有" + semaphore.availablePermits() + "台游戏机.");
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e1) {
					}
					
					semaphore.release();
					System.out.println("num: " + num + " 结束打游戏. 还有" + semaphore.availablePermits() + "台游戏机.");
				}				
			});
		}
		executor.shutdown();
	}
}


四、Exchanger
1. 功能
两个线程可以交换对象的同步点,每个线程给出对象,并接受其他线程返回时给出的对象。

2. 使用方法
1)新建Exchanger对象。
2)每个线程交换对象时,调用exchanger.exchange(),完成对象交换。

3. 示例
场景: 一黄牛最近拿到一部小米手机,想卖给一位同事,双方约好在公司门口交易,一手交钱,一手交货。
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExchangerTest {
	public static void main(String[] args) {
		final Exchanger exchanger = new Exchanger();
		
		ExecutorService executor = Executors.newCachedThreadPool();
		executor.execute(new Runnable(){
			@Override
			public void run() {
				String money = "钞票";
				System.out.println("同事有: " + money);
				try {
					String goods1 = (String) exchanger.exchange(money);
					System.out.println("同事有: " + goods1);
				} catch (InterruptedException e) {					
				}				
			}			
		});
		
		executor.execute(new Runnable(){
			@Override
			public void run() {
				String goods2 = "小米手机";
				System.out.println("黄牛有: " + goods2);

				//黄牛很忙,迟到一会
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e1) {
				}
				
				try {					
					String money = (String) exchanger.exchange(goods2);
					System.out.println("黄牛有: " + money);
				} catch (InterruptedException e) {				
				}			
			}			
		});		
		executor.shutdown();
	}
}
0
0
分享到:
评论

相关推荐

    linux网路编程 中文 23M 版

    6 使用其他编辑器................................................................................................... 2.2 Linux下的G C C 编译器工具集.......................................... 19 2.2.1 ...

    Java并发编程:用AQS写一把可重入锁

    AQS是J.U.C包下AbstractQueuedSynchronizer抽象的队列式的同步器的简称,这是一个抽象类,它定义了一套多线程访问共享资源的同步器框架,J.U.C包下的许多同步类实现都依赖于它,比如ReentrantLock/Semaphore/...

    尚gg大数据项目实战电商数仓系统开发教程.txt

    34_数仓采集_分类型拦截器.avi! b5 ^. a8 ^; }$ x8 z) l2 U3 }" p 35_数仓采集_日志采集Flume启动停止脚本.avi2 ~/ r- J: h$ U, q/ e# e7 k% M 36_数仓采集_Kafka集群安装.avi3 L6 `7 F& o/ U6 F" U5 U 37_数仓采集_...

    【尚硅谷】徐靖博 最新电商项目实战(完结)

    r1 b# x1 k3 e 137.01 交叉检索redis 138.02 交叉检索redis* Y7 `1 z9 P" D% J+ E 139.03 判断交叉检索的key 140.04 redis的使用总结: C& g/ P ^; B. n8 Y6 d1 C# ^9 l 141.05 一些小问题. @( |. p' J! V5 s; Z+ E ...

    [游戏开发] 达达房卡麻将二次开发VIP系统学习课程 [MP4] (16.66G)

    │ 第011课动画编辑器的使用.rar$ N1 Y4 L$ J, g# L, c) x* T4 s* @ │ 第012课骨骼动画组件的使用.rar& G. _4 U0 u; U0 V: p% | │ 第013课mask_layout_scrollview组件的使用.rar {& g, [) W2 l0 b# t) M& V │ 第...

    互联网创意产品众筹平台

    │ 11.Maven项目模块划分-引用依赖包( f- {5 L4 F2 i8 z+ c* U │ 12.项目环境搭建细节-监听器 │ 13.项目环境搭建细节-过滤器 │ 14.项目环境搭建细节-核心控制器 │ 15.项目环境搭建细节-spring-springmvc相关配置...

    微软活动目录管理管理简明手册

    4 k9 H# a7 L4 C" C全局目录服务器是一个域控制器,活动目录建立的第一个域控制器自动成为全局目录服务器。全局目录就放在全局目录服务器上。 5 E4 E: a& _- c% ~1 X 4 Z z8 n. F8 D8 @1 `% A/ p% x4 s2.活动目录的...

    uCOS-II.zip_uCOS 商业_ucos_产品调度_软件工具

    u C / O S 是一种公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统,商业应用需要付费。 μC/OS-II 的前身是μC/OS,最早出自于1992 年美国嵌入式系统专家Jean J.Labrosse 在《嵌入式系统编程》杂志的5 月和...

    uc/OS II 源代码

    u C / O S 是一种公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统,商业应用需要付费。 μC/OS-II 的前身是μC/OS,最早出自于1992 年美国嵌入式系统专家Jean J.Labrosse 在《嵌入式系统编程》杂志的5 月和...

    java面试题以及技巧

    │ │ j2sdk-1_4_2-doc.zip │ │ Java Programming Language (SL-275).txt │ │ langspec-3.0.zip │ │ SCJP Certification Training.htm │ │ SCJP 考纲.doc │ │ SL275_OH_GB.pdf │ │ Sun Certified ...

    java面试题目与技巧1

    │ │ j2sdk-1_4_2-doc.zip │ │ Java Programming Language (SL-275).txt │ │ langspec-3.0.zip │ │ SCJP Certification Training.htm │ │ SCJP 考纲.doc │ │ SL275_OH_GB.pdf │ │ Sun Certified ...

    java面试题及技巧4

    │ │ j2sdk-1_4_2-doc.zip │ │ Java Programming Language (SL-275).txt │ │ langspec-3.0.zip │ │ SCJP Certification Training.htm │ │ SCJP 考纲.doc │ │ SL275_OH_GB.pdf │ │ Sun Certified ...

    java面试题及技巧3

    │ │ j2sdk-1_4_2-doc.zip │ │ Java Programming Language (SL-275).txt │ │ langspec-3.0.zip │ │ SCJP Certification Training.htm │ │ SCJP 考纲.doc │ │ SL275_OH_GB.pdf │ │ Sun Certified ...

    java面试题以及技巧6

    │ │ j2sdk-1_4_2-doc.zip │ │ Java Programming Language (SL-275).txt │ │ langspec-3.0.zip │ │ SCJP Certification Training.htm │ │ SCJP 考纲.doc │ │ SL275_OH_GB.pdf │ │ Sun Certified ...

    2017最新大数据架构师精英课程

    h+ R9 L1 w, U* T6 J# M 93_job 全排序-自定义分区类2 n% h" `: b4 c) C3 J9 S 94_job二次排序5 t3 Z2 R- ]( a: s* c0 Z 95_从db输入数据进行mr计算: L. M4 I6 y, R2 l/ u/ L 96_输出数据到db中 97_...

    linux.chm文档

    find / -perm -u+s 罗列一个系统中所有使用了SUID控制的文件 chmod u+s /bin/file1 设置一个二进制文件的 SUID 位 - 运行该文件的用户也被赋予和所有者同样的权限 chmod u-s /bin/file1 禁用一个二进制文件的 SUID...

    整理后java开发全套达内学习笔记(含练习)

    synchronized (关键字) 同步(锁) ['siŋkrәnaiz] Thread [java] 线程 [θred] throw (关键字) throws (关键字) [θrәu] 抛出(异常) transient (关键字) 瞬变;临时的['trænziәnt]'(可序列化) valid 正确的,...

    CISCO 技术大集合

    Router1和Router2的E0端口均使用了C类地址192.1.0.0作为网络地址,Router1的E0的网络地址为192.1.0.128,掩码为255.255.255.192, Router2的E0的网络地址为192.1.0.64,掩码为255.255.255.192,这样就将一个C类网络地址...

    java经典面试2010集锦100题(不看你后悔)

    下面不属于基本类型的是:c (选择1项) A) boolean B) long C) String D) byte 题目2:d 如下程序中: (1)public class CharToInt (2){ (3) public static void main(String[] args) (4) { (5) int a,b=...

Global site tag (gtag.js) - Google Analytics