1).Android 价值千万   java线程专题:Wait&notify&join&Yield

http://blog.csdn.net/whb20081815/article/details/65627387

2).Android 价值千万    java多线程同步 <二>Callable和Future&FutureTask

http://blog.csdn.net/whb20081815/article/details/65630694

3).Android 价值千万    java多线程<三>生产者消费者模型四种实现方法

http://blog.csdn.net/whb20081815/article/details/65635647

4).

Android 价值千万    java多线程同步 <四> synchronized&Lock&Atomic6种方式

http://blog.csdn.net/whb20081815/article/details/66971983

5).Android 价值千万java多线程同步 <五>CountDownLatch(计数器)和Semaphore(信号量)

http://blog.csdn.net/whb20081815/article/details/68498371

Semaphore

Semaphore是一个计数信号量,它的本质是一个"共享锁",以控制某个资源可被同时访问的个数,提供同步机制

信号量维护了一个信号量许可集。线程可以通过调用acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。

场景:Semaphore实现的功能就类似厕所有5个坑,假如有10个人要上厕所,那么同时只能有多少个人去上厕所呢?同时只能有5个人能够占用,当5个人中 的任何一个人让开后,其中等待的另外5个人中又有一个人可以占用了。

可以手动控制顺序:信号量保证它们调用的顺序(即先进先出;FIFO),Semaphore的实现使用AQS的状态来保存许可数量,它实现了公平和非公平两种策略

// 定义2个新号量
Semaphore semaphore = new Semaphore(4); // 定义2个新号量/*** 和其他的区别:* 一般的情况:多个人多线程访问同一个账号* 信号量的场景:多个人多线访问多个账号也没有问题,同时能解决多个人多线程访问同一个账号* Semaphore可以控制某个资源可被同时访问的个数,其他是多个线程同时访问*/
public void testSemaphore(){// 创建并发访问的账户MyCount myCount = new MyCount("95599200901215522", 10000);// 创建一个锁对象Lock lock = new ReentrantLock();// 创建一个线程池ExecutorService pool = Executors.newCachedThreadPool();// 创建一些并发访问用户,一个信用卡,存的存,取的取,好热闹啊UserSemaphore u1 = new UserSemaphore("张三", myCount, -4000, lock, semaphore);UserSemaphore u2 = new UserSemaphore("张三他爹", myCount, 6000, lock, semaphore);UserSemaphore u3 = new UserSemaphore("张三他弟", myCount, -8000, lock, semaphore);UserSemaphore u4 = new UserSemaphore("张三老婆", myCount, 800, lock, semaphore);// 在线程池中执行各个用户的操作pool.execute(u1);pool.execute(u2);pool.execute(u3);pool.execute(u4);
}
/*** 信用卡的用户*/
public class UserSemaphore implements Runnable {private String name; // 用户名private MyCount myCount; // 所要操作的账户private int iocash; // 操作的金额,当然有正负之分了private Lock myLock; // 执行操作所需的锁对象UserSemaphore(String name, MyCount myCount, int iocash, Lock myLock, Semaphore isOk) {this.name = name;this.myCount = myCount;this.iocash = iocash;this.myLock = myLock;this.mIsOk=isOk;}private Semaphore mIsOk;public void run() {// 获取锁// 执行现金业务try {if (mIsOk.availablePermits() > 0) {System.out.println("线程" + Thread.currentThread().getName()+ "启动,进入银行,有位置立即去存钱");} else {System.out.println("线程" + Thread.currentThread().getName()+ "启动,进入银行,无位置,去排队等待等待");}mIsOk.acquire();System.out.println("UserSynch" + name + "正在操作" + myCount + "账户,金额为" + iocash+ ",当前金额为" + myCount.getCash());myCount.setCash(myCount.getCash() + iocash);System.out.println(name + "操作" + myCount + "账户成功,金额为" + iocash+ ",当前金额为" + myCount.getCash());mIsOk.release();} catch (InterruptedException e) {e.printStackTrace();}}
}

CountDownLatch

   CountDownLatch利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。它可以代替Notify和wait的实现:整理和分析流程

每次调用 countDown() 方法, CountDownLatch 对象内部计数器减一。

当内部计数器达到0时, CountDownLatch 对象唤醒全部使用await() 方法,不是Wait()方法睡眠的线程们。

CountDownLatch类有3个基本元素:

  1. 初始值决定CountDownLatch类需要等待的事件的数量。
  2. await() 方法, 被等待全部事件终结的线程调用。
  3. countDown() 方法,事件在结束执行后调用。
 //有2个线程完成才开始某个线程final CountDownLatch latch = new CountDownLatch(2);public void testCountDownLatch(){// 创建并发访问的账户MyCount myCount = new MyCount("95599200901215522", 10000);// 创建一个线程池ExecutorService pool = Executors.newCachedThreadPool();// 创建一些并发访问用户,一个信用卡,存的存,取的取,好热闹啊UserCountDownLatchWait u1 = new UserCountDownLatchWait("张三", myCount, -4000, true, latch);UserCountDownLatch u2 = new UserCountDownLatch("张三他爹", myCount, 6000, false, latch);UserCountDownLatch u3 = new UserCountDownLatch("张三他弟", myCount, -8000, false, latch);
//        UserCountDownLatchWait u4 = new UserCountDownLatchWait("张三老婆", myCount, 800, false, latch);// 在线程池中执行各个用户的操作pool.execute(u1);pool.execute(u2);pool.execute(u3);
//        pool.execute(u4);}
UserCountDownLatchWait(String name, MyCount myCount, int iocash, boolean isWait, CountDownLatch myLock) {this.name = name;this.myCount = myCount;this.iocash = iocash;this.myLock = myLock;isNeedWait = isWait;
}public void run() {// 获取锁// 执行现金业务try {if (isNeedWait) {/** java.lang.IllegalMonitorStateException: object not locked by thread before wait()*/System.out.print("name==" + name + "isNeedWait==" + isNeedWait);myLock.wait();}System.out.println(name + "正在操作" + myCount + "账户,金额为" + iocash+ ",当前金额为" + myCount.getCash() + isNeedWait);myCount.setCash(myCount.getCash() + iocash);System.out.println(name + "操作" + myCount + "账户成功,金额为" + iocash+ ",当前金额为" + myCount.getCash() + isNeedWait);// 释放锁,否则别的线程没有机会执行了if (!isNeedWait) {myLock.countDown();}} catch (InterruptedException e) {e.printStackTrace();}
}

总结:

  CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;

Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。

思考: 
    在很多情况下,可能有多个线程需要访问数目很少的资源。假想在服务器上运行着若干个回答客户端请求的线程。这些线程需要连接到同一数据库,但任一时刻 
    只能获得一定数目的数据库连接。你要怎样才能够有效地将这些固定数目的数据库连接分配给大量的线程? 
    
答:1.给方法加同步锁,保证同一时刻只能有一个人去调用此方法,其他所有线程排队等待,但是此种情况下即使你的数据库链接有10个,也始终只有一个处于使

        用状态。这样将会大大的浪费系统资源,而且系统的运行效率非常的低下。

2.另外一种方法当然是使用信号量,通过信号量许可与数据库可用连接数相同的数目,将大大的提高效率和性能。

AS代码地址:

Android 价值千万java多线程同步 lt;五CountDownLatch(计数器)和Semaphore(信号量)相关推荐

  1. java多线程同步的五种方法

    一.前几天去面试,被大师问道一些很基础的问题,感觉自己答的很不满意,闲话不多说,进入正题. 二.为什么要使用同步? 因为当我们有多个线程要同时访问同一个变量或对象时,如果这些线程中午既有读又有写操作时 ...

  2. Java多线程闲聊(五):AQS

    Java多线程闲聊(五):AQS 前言 今天的第二篇了,我肚子里也没有那么多的墨水,所以这第二篇的前言,就免了吧. 正文 AQS,AbstractQueueSynchronizer,是Java官方所提 ...

  3. java 什么是线程同步,java多线程同步集合是什么?并发集合是什么?

    java中关于集合的内容也是十分丰富的,而且相关的知识点也是十分多的.多线程集合所涵盖的范围是十分广阔的.今天就来为大家介绍一下,java多线程同步集合是什么以及并发集合是什么?一起来看看吧. 首先我 ...

  4. Java多线程同步机制

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个 ...

  5. java多线程同步与死锁_浅析Java多线程中的同步和死锁

    Value Engineering 1基于Java的多线程 多线程是实现并发机制的一种有效手段,它允许编程语言在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间相互独立,且与进程一样拥有独立 ...

  6. Java多线程同步之使用Lock实现车辆入库出库管理

    Java多线程同步之使用Lock实现车辆入库出库管理 个人笔记: 实现:车库有n个车位,现在有m辆车试图进入车库,每辆车停留随机秒数后离开 首先创建一个Garage车库类,Garage有空间属性和最大 ...

  7. Java学习笔记---多线程同步的五种方法

    一.引言 前几天面试,被大师虐残了,好多基础知识必须得重新拿起来啊.闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会 ...

  8. java 多线程同步_浅谈Java多线程(状态、同步等)

    Java多线程是Java程序员必须掌握的基本的知识点,这块知识点比较复杂,知识点也比较多,今天我们一一来聊下Java多线程,系统的整理下这部分内容. 一.Java中线程创建的三种方式: 1.通过继承T ...

  9. java 多线程同步问题_Java多线程同步问题:一个小Demo完全搞懂

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.一个简单的Demo引发的血案 关于线程同步问题我们从一个 ...

最新文章

  1. Keepalived+lvs+httpd之负载均衡
  2. 《Ext JS高级程序设计》节选: 一个结合DataWrite和RowEditor的Grid示例(1)
  3. KVM 实现机制---(很經典)
  4. 国内数据中心分布及供电系统概述
  5. 判断是否为微信环境下打开的网页
  6. 公开课精华 | 无人驾驶中感知的挑战与尝试
  7. Hibernate里面session.get()和session.load()的区别
  8. Java 设计模式之 Visitor 访问者模式
  9. UVALive - 6436
  10. Jmeter-Ant 生成测试报告
  11. Ubuntu 安装Jenkins报错
  12. 加密芯片算法移植方案的优点
  13. 《极客学院 --NSAttributedString 使用详解-4-UITextKit 简介》学习笔记(待处理)...
  14. 汇编指令大全及标志位
  15. 发那科机器人圆弧指令怎么用_发那科机器人PR指令
  16. 《MBA一日读2.0 读书笔记》
  17. 【5G核心网】PFCP Message PFCP 消息
  18. 云迁移实践:VMware虚拟机迁移到腾讯云
  19. 如何看台式机计算机编号,如何查看台式电脑的主机编号和型号
  20. table制作课程表案例

热门文章

  1. 实时读取屏幕识别指定颜色
  2. 不能不知道的电源稳压器的选择
  3. CXF soap message 协议从 1.1 转为 1.2
  4. 4.3Bayesian approach to univariate normal distribution
  5. 当我给女同学用python画了个圣诞树后……
  6. java高校网上报销系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
  7. diff文件对比命令
  8. 【深度学习】实验4布置:脑部 MRI 图像分割
  9. 四川大学计算机网络期末复习,四川大学计算机基础期末考试试卷07-08
  10. Python Flask简介请求勾子