本文转自http://blog.csdn.net/u010942020/article/details/79352560 感谢作者

一、Java多线程总结:

描述线程的类:Runable和Thread都属于java.lang包。

内置锁synchronized属于jvm关键字,内置条件队列操作接口Object.wait()/notify()/notifyAll()属于java.lang包。

提供内存可见性和防止指令重排的volatile属于jvm关键字。

而java.util.concurrent包(J.U.C)中包含的是java并发编程中有用的一些工具类,包括几个部分:

locks部分:包含在java.util.concurrent.locks包中,提供显式锁(互斥锁和速写锁)相关功能。

atomic部分:包含在java.util.concurrent.atomic包中,提供原子变量类相关的功能,是构建非阻塞算法的基础。

executor部分:散落在java.util.concurrent包中,提供线程池相关的功能。

collections部分:散落在java.util.concurrent包中,提供并发容器相关功能。

tools部分:散落在java.util.concurrent包中,提供同步工具类,如信号量、闭锁、栅栏等功能。

二、同步工具类详解

1、Semaphore信号量:跟锁机制存在一定的相似性,semaphore也是一种锁机制,所不同的是,reentrantLock是只允许一个线程获得锁,而信号量持有多个许可(permits),允许多个线程获得许可并执行。可以用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。

示例代码:

5 public class TIJ_semaphore {

6 public static void main(String[] args) {

7 ExecutorService exec = Executors.newCachedThreadPool();

8 final Semaphore semp = new Semaphore(5); // 5 permits

9

10 for (int index = 0; index < 20; index++) {

11 final int NO = index;

12 Runnable run = new Runnable() {

13 public void run() {

14 try {

// if 1 permit avaliable, thread will get a permits and go; if no permit avaliable, thread will block until 1 avaliable

15 semp.acquire();

16 System.out.println("Accessing: " + NO);

17 Thread.sleep((long) (10000);

18 semp.release();

19 } catch (InterruptedException e) {

20 }

21 }

22 };

23 exec.execute(run);

24 }

25 exec.shutdown();

26 }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

2、CountDownLatch闭锁:允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

主要方法:

1. CountDownLatch.await():将某个线程阻塞住,直到计数器count=0才恢复执行。

2. CountDownLatch.countDown():将计数器count减1。

使用场景:

1. 实现最大的并行性:有时我们想同时启动多个线程,实现最大程度的并行性。例如,我们想测试一个单例类。如果我们创建一个初始计数为1的CountDownLatch,并让所有线程都在这个锁上等待,那么我们可以很轻松地完成测试。我们只需调用 一次countDown()方法就可以让所有的等待线程同时恢复执行。

2. 开始执行前等待n个线程完成各自任务:例如应用程序启动类要确保在处理用户请求前,所有N个外部系统已经启动和运行了。

3. 死锁检测:一个非常方便的使用场景是,你可以使用n个线程访问共享资源,在每次测试阶段的线程数目是不同的,并尝试产生死锁。

4. 计算并发执行某个任务的耗时。

示例代码:

public class CountDownLatchTest {

public void timeTasks(int nThreads, final Runnable task) throws InterruptedException{

final CountDownLatch startGate = new CountDownLatch(1);

final CountDownLatch endGate = new CountDownLatch(nThreads);

for(int i = 0; i < nThreads; i++){

Thread t = new Thread(){

public void run(){

try{

startGate.await();

try{

task.run();

}finally{

endGate.countDown();

}

}catch(InterruptedException ignored){

}

}

};

t.start();

}

long start = System.nanoTime();

System.out.println("打开闭锁");

startGate.countDown();

endGate.await();

long end = System.nanoTime();

System.out.println("闭锁退出,共耗时" + (end-start));

}

public static void main(String[] args) throws InterruptedException{

CountDownLatchTest test = new CountDownLatchTest();

test.timeTasks(5, test.new RunnableTask());

}

class RunnableTask implements Runnable{

@Override

public void run() {

System.out.println("当前线程为:" + Thread.currentThread().getName());

}

}

执行结果为:

打开闭锁

当前线程为:Thread-0

当前线程为:Thread-3

当前线程为:Thread-2

当前线程为:Thread-4

当前线程为:Thread-1

闭锁退出,共耗时1109195

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

3、CyclicBarrier栅栏:用于阻塞一组线程直到某个事件发生。所有线程必须同时到达栅栏位置才能继续执行下一步操作,且能够被重置以达到重复利用。而闭锁是一次性对象,一旦进入终止状态,就不能被重置。

示例代码:

public class CyclicBarrierTest {

private final CyclicBarrier barrier;

private final Worker[] workers;

public CyclicBarrierTest(){

int count = Runtime.getRuntime().availableProcessors();

this.barrier = new CyclicBarrier(count,

new Runnable(){

@Override

public void run() {

System.out.println("所有线程均到达栅栏位置,开始下一轮计算");

}

});

this.workers = new Worker[count];

for(int i = 0; i< count;i++){

workers[i] = new Worker(i);

}

}

private class Worker implements Runnable{

int i;

public Worker(int i){

this.i = i;

}

@Override

public void run() {

for(int index = 1; index < 3;index++){

System.out.println("线程" + i + "第" + index + "次到达栅栏位置,等待其他线程到达");

try {

//注意是await,而不是wait

barrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

return;

} catch (BrokenBarrierException e) {

e.printStackTrace();

return;

}

}

}

}

public void start(){

for(int i=0;i

new Thread(workers[i]).start();

}

}

public static void main(String[] args){

new CyclicBarrierTest().start();

}

}

执行结果为:

线程0第1次到达栅栏位置,等待其他线程到达

线程1第1次到达栅栏位置,等待其他线程到达

线程2第1次到达栅栏位置,等待其他线程到达

线程3第1次到达栅栏位置,等待其他线程到达

所有线程均到达栅栏位置,开始下一轮计算

线程3第2次到达栅栏位置,等待其他线程到达

线程2第2次到达栅栏位置,等待其他线程到达

线程0第2次到达栅栏位置,等待其他线程到达

线程1第2次到达栅栏位置,等待其他线程到达

所有线程

java 栅栏_Java并发包之闭锁/栅栏/信号量(转)相关推荐

  1. java 信号量 闭锁_Java并发包之闭锁/栅栏/信号量

    二.同步工具类详解 1.Semaphore信号量:跟锁机制存在一定的相似性,semaphore也是一种锁机制,所不同的是,reentrantLock是只允许一个线程获得锁,而信号量持有多个许可(per ...

  2. Java并发包之闭锁/栅栏/信号量及并发模型和锁

    threadLocal能够为每一个线程维护变量副本,常用于在多线程中用空间换时间 进程死锁:进程死锁,指多个进程循环等待他方占有的资源而一直等待下去的局面: 进程活锁:线程1,2需要同时占有a,b才可 ...

  3. Java并发包之闭锁/栅栏/信号量(转)

    本文转自http://blog.csdn.net/u010942020/article/details/79352560 感谢作者 一.Java多线程总结: 描述线程的类:Runable和Thread ...

  4. java 栅栏_Java 并发工具类(栅栏 CyclicBarrier )

    CyclicBarrier适用于这样的情况:你希望创建一组任务,它们并行地执行工作,然后在下一个步骤之前等待,直到所有任务都完成.栅栏和闭锁的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行. ...

  5. java多线程并发之旅-20-同步工具类。闭锁/栅栏/信号量/阻塞队列/FutureTask

    同步工具类 同步工具类主要包括闭锁(如CountDownLatch),栅栏(如CyclicBarrier),信号量(如Semaphore)和阻塞队列(如LinkedBlockingQueue)等: F ...

  6. java并发编程笔记3-同步容器并发容器闭锁栅栏信号量

    一.同步容器: 1.Vector容器实现了List接口,Vector实际上就是一个数组,和ArrayList类似,但是Vector中的方法都是synchronized方法,即进行了同步措施.保证了线程 ...

  7. saml java实现_Java 的 SAML 开发包 java-saml

    软件介绍 java-saml 是 Java 的 SAML 开发包. Maven: com.onelogin java-saml 2.4.0 示例代码:Map samlData = new HashMa ...

  8. 【源码+教程】Java课设项目_12款最热最新Java游戏项目_Java游戏开发_Java小游戏_飞翔的小鸟_王者荣耀_超级玛丽_推箱子_黄金矿工_贪吃蛇

    马上就要期末了,同学们课设做的如何了呢?本篇为大家带来了12款热门Java小游戏项目的源码和教程,助力大家顺利迎接暑假![源码+教程]Java课设项目_12款最热最新Java游戏项目_Java游戏开发 ...

  9. java上此类开发包非常多,想问问各位C++同仁知道什么比较好的开发包for C/C++的吗

    以前一直采用apache+expat直接对付http+xml的方式来实现soap处理,java上此类开发包非常多,想问问各位C++同仁知道什么比较好的开发包for  C/C++的吗? axis for ...

  10. 搜寻Java Card SIM开发包,跑了一趟江南科友

    昨天晚上我在公司加班看GSM Java智能卡开发内容.上午我来公司基本把书上的示例程序看完.上午我就做了点这些. 下午我找到示例相关的代码贴到Eclipse的编辑窗口中,发现缺少Java Card S ...

最新文章

  1. Python基础学习笔记--字符串、列表
  2. 《数据竞赛白皮书·下篇》发布,开源办好一场数据竞赛的实践方法论
  3. 鸿蒙系统8月7号,主动告别安卓,华为或很快推出搭载鸿蒙系统的手机
  4. 使用开源CRM进行客户关系管理(2)
  5. 【Linux】一步一步学Linux——chage命令(92)
  6. 让vue-router渲染为指定的标签
  7. Oracle中查询、禁用、启用、删除表外键
  8. 相似图像识别检 —基于图像签名(LSH)
  9. Linux命令之 users -- 显示当前登录的用户
  10. 上岸 | 青椒博士毕业后未返校任教,被判返还高校41万余元
  11. mysql拼接两字段查询
  12. 人工智能在安全漏洞方面的应用_智慧消防平台的智慧在哪方面?
  13. 用java写出死锁的例子_【面试】请写一个java死锁的例子-Go语言中文社区
  14. 安卓一键清理内存_教大家安卓怎么清理内存-装修攻略
  15. [Campus]我的大学
  16. java 处理txt_java 读写 txt 文件
  17. Python2.6+PyQt4.8+eric4+汉化+开发教程
  18. freemarker ftl java_FreeMarker学习1(Ftl)
  19. ExifTool如何格式化日期和时间信息以进行书写
  20. 人到中年:最近看到的几篇好文

热门文章

  1. 分布式技术(6) 后端接口设计方案
  2. 基因重组-冲刺日志(第八天)
  3. 百度地图API和2D/3D地图的转换
  4. Unity材质偏移(贴图纹理偏移)实现流动效果【记录一下】
  5. sql注入学习笔记1
  6. 浏览器主页被篡改怎么办
  7. 当你的浏览器页面被篡改时,我们该怎么办
  8. U盘不能分区,不能格式化,解决方案
  9. 蝴蝶效应,青蛙现象,鳄鱼法则,鲇鱼效应,羊群效...
  10. 动手学深度学习 - 11.1. 数学符号 (notation)