一、Semaphore介绍

Semaphore意思为信号量,是用来控制同时访问特定资源的线程数数量。它的本质上其实也是一个共享锁。Semaphore可以用于做流量控制,特别是公用资源有限的应用场景。例如:某个停车场车位只有10个,一开始停车场没有车辆所有车位全部空着,然后先后到来八辆车,停车场车位够,安排进去停车,然后又来三辆,这个时候由于只有两个停车位,所有只能停两辆,其余一辆必须在外面候着,直到停车场有空车位,当然以后每来一辆都需要在外面候着。当停车场有车开出去,里面有空位了,则安排一辆车进去。这个场景就是典型的信号量应用场景。

我们可以把停车场比喻成Semaphore,然后车辆就是一个一个的线程。车位就是许可数10。当来一辆车的时候许可数就减一,知道许可数减为0。这个时候已经没有停车位了。所以车辆必须排队等候车位。过一段时间有一辆车开走了,这个时候许可数就增加一。同时外面的车就可以进来一辆。是否按照排队次序进来就看是否是公平锁还是非公平锁。

二、SemaphoreAPI使用介绍

       2.1、构造函数:

  1. Semaphore(int permits) :创建具有给定的许可数和非公平的公平设置的 Semaphore。

  2. Semaphore(int permits, boolean fair) :创建具有给定的许可数和给定的公平设置的 Semaphore。

2.2、信号量获取:

1.  Semaphore提供了acquire()方法来获取一个许可。

2.3、信号量释放:

1.  Semaphore提供release()来释放许可。

2.4、其他方法:

1.   intavailablePermits():返回此信号量中当前可用的许可证数。

2.   intgetQueueLength():返回正在等待获取许可证的线程数。

3.   booleanhasQueuedThreads():是否有线程正在等待获取许可证。

·      4.   void reducePermits(int reduction):减少reduction个许可证,是个protected方法。

·      5.   Collection getQueuedThreads():返回所有等待获取许可证的线程集合,是个protected方

法。

三、应用实例

 import java.util.concurrent.Semaphore;

 public class SemaphoreUserCase {

     public static void main(String[] args)  {
//停车位一共2个
Parking parking = new Parking(2);
for(int i = 0;i < 5;i++){
new Car(parking).start();
}
} }
class Parking {
//信号量
private Semaphore semaphore;
Parking(int count){
//初始化信号量
semaphore = new Semaphore(count);
}
public void park(){
try {
//获取信号量
semaphore.acquire();
long time = (long) (Math.random() * 100);
System.out.println(Thread.currentThread().getName() + "进入停车场,停车" + time + "秒..." );
Thread.sleep(time);
System.out.println(Thread.currentThread().getName() + "开出停车场...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//将信号量递减
semaphore.release();
}
}
}
class Car extends Thread{ Parking parking;
Car(Parking parking){
this.parking = parking;
}
@Override
public void run() {
//进入停车场停车
parking.park();
} }
 Thread-0进入停车场,停车2秒...
Thread-2进入停车场,停车58秒...
Thread-0开出停车场...
Thread-3进入停车场,停车45秒...
Thread-3开出停车场...
Thread-4进入停车场,停车11秒...
Thread-2开出停车场...
Thread-4开出停车场...
Thread-1进入停车场,停车95秒...
Thread-1开出停车场...

从上面结果我们可以很容易的看出来,停车场只有两个位置。当被占用的时候,其他车辆只能等待。当信号量为0的时候,线程会被阻塞。

四、Exchanger介绍

Exchanger意思为交换者,作为Java并发工具类他的作用是交换过个线程中的数据。它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据。当第一个线程调用exchange()方法,那么他会一直等待第二个线程调用exchange()方法。直到交换数据。Exchanger工具类最常用于遗传学上的应用。遗传算法里需要选出两个人作为交配对象,这时候会交换 两人的数据,并使用交叉规则得出2个交配结果。Exchanger也可以用在校对数据。比如我们需要将纸制银流通过人工的方式录入成电子银行流水,为了避免错误,采用AB岗两人进行录入,录入到Excel之后,系统需要加载这两个Excel,并对这两个Excel数据进行校对,看看是否录入的一致。

五、ExchangerAPI介绍

       5.1、构造函数:

  1. Exchanger()创建一个新的 Exchanger

  5.2、其他API:

1.   exchange(V x) 等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。

2. exchange(V x, long timeout, TimeUnit unit) 等待另一个线程到达此交换点(除非当前线程被中断,或者超出了指定的等待时间),然后将给定的对象传送给该线程,同时接收该线程的对象。

六、应用实例

 import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class ExchangerUserCase { private static final Exchanger<String> exgr = new Exchanger<String>(); private static ExecutorService threadPool = Executors.newFixedThreadPool(2); public static void main(String[] args) { threadPool.execute(new Runnable() {
@Override
public void run() {
try {
String A = "";// A录入银行流水数据
exgr.exchange(A);
} catch (InterruptedException e) {
}
}
}); threadPool.execute(new Runnable() {
@Override
public void run() {
try {
String B = "";// B录入银行流水数据
String A = exgr.exchange("B");
System.out.println("A和B数据是否一致:" + A.equals(B) + ",A录入的是:"
+ A + ",B录入是:" + B);
} catch (InterruptedException e) {
}
}
}); threadPool.shutdown(); } }
 A和B数据是否一致:false,A录入的是:1000,B录入是:2000

Java并发之Semaphore和Exchanger工具类简单介绍的更多相关文章

  1. Java学习笔记43(打印流、IO流工具类简单介绍)

    打印流: 有两个类:PrintStream,PrintWriter类,两个类的方法一致,区别在于构造器 PrintStream:构造方法:接收File类型,接收字符串文件名,接收字节输出流(Outpu ...

  2. 高并发之Semaphore、Exchanger、LockSupport

    本系列研究总结高并发下的几种同步锁的使用以及之间的区别,分别是:ReentrantLock.CountDownLatch.CyclicBarrier.Phaser.ReadWriteLock.Stam ...

  3. Java并发之Semaphore的使用

    Java并发之Semaphore的使用 一.简介 今天突然发现,看着自己喜欢的球队发挥如此的棒,然后写着博客,这种感觉很爽.现在是半场时间,就趁着这个时间的空隙,说说Java并发包中另外一个重量级的类 ...

  4. Java判断不为空的工具类总结

    1.Java判断是否为空的工具类,可以直接使用.包含,String字符串,数组,集合等等. package com.bie.util; import java.util.Collection; imp ...

  5. Java字符串转16 进制工具类Hex.java

    Java字符串转16 进制工具类Hex.java 学习了:https://blog.csdn.net/jia635/article/details/56678086 package com.strin ...

  6. Java中的AES加解密工具类:AESUtils

    本人手写已测试,大家可以参考使用 package com.mirana.frame.utils.encrypt; import com.mirana.frame.constants.SysConsta ...

  7. java里poi操作excel的工具类(兼容各版本)

    转: java里poi操作excel的工具类(兼容各版本) 下面是文件内具体内容,文件下载: import java.io.FileNotFoundException; import java.io. ...

  8. java.util.Arrays----操作数组的工具类

    java.util.Arrays操作数组的工具类,里面定义了很多操作数组的方法 1.boolean equals(int[] a,int[] b):判断两个数组是否相等. 2.String toStr ...

  9. oc-12-NSString 类简单介绍及用法

    // 11-[掌握]NSString 类简单介绍及用法 #import <Foundation/Foundation.h> int main(int argc, const char * ...

随机推荐

  1. WPF 实现拖动工具箱效果

    原文:WPF 实现拖动工具箱效果 1.效果 点击左边的矩形拖动到右边canvas面板,右边面板添加矩形 2.布局 左边是个StockPanel,上面有个矩形,右边是个Canvas面板. 矩形是源,Ca ...

  2. WPF与缓动(一) N次缓动

    原文:WPF与缓动(一) N次缓动   WPF与缓动(一)  N次缓动                                                                  ...

  3. C#开发奇技淫巧一:调试windows系统服务

    原文:C#开发奇技淫巧一:调试windows系统服务 windows系统服务不能直接运行,只能在安装完服务之后启动.暂停.继续.停止服务,导致服务的调试不能使用一般的断点调试. 要调试系统服务,可以采 ...

  4. SyncML是一平台无关的信息同步标准协议集

    SyncML (Synchronization Markup Language)是一平台无关的信息同步标准协议集.分为SyncML数据传输协议(SyncML-DS)和SyncML设备管理协议(Sync ...

  5. redis zincrby zadd 遇到的问题

    在维护代理池时 报错1: zincrby(REDIS_KEY,proxy,-1)redis.exceptions.ResponseError: value is not a valid float 查 ...

  6. 调用API函数减少c#内存占用(20+m减至1m以下)

    原文:调用API函数减少c#内存占用(20+m减至1m以下) c#虽然内置垃圾回收机制,但是并不能解决程序占用内存庞大的问题,如果我们仔细观察任务管理器,我们会发现一个程序如果最小化的时候,它所占用的 ...

  7. Ionic3开发环境搭建-VS Code

    原文:Ionic3开发环境搭建-VS Code 一.Ionic3在VS Code中的开发环境搭建 1.全局安装Ionic包 npm install -g cordova ionic 使用 ionic ...

  8. Win8MetroC#数字图像处理--2.1图像灰度化

    原文:Win8MetroC#数字图像处理--2.1图像灰度化   [函数说明] 图像灰度化函数GrayProcess(WriteableBitmap src) [算法说明]   图像灰度化就是去掉彩色 ...

  9. iText类库再pdf中显示中文字体

    using iTextSharp.text; using System; using System.Collections.Generic; using System.IO; using System ...

  10. Win10版《芒果TV》全平台直播第89届奥斯卡颁奖典礼,特设第二演播室带来一手资讯

    芒果TV为所有中国影迷们带来的:今年的奥斯卡直播与往年格外不同,为了让网友们观看这场盛典得到多维度体验,不管是来看热闹的还是看门道的都看得开心尽兴,芒果TV特设第二演播室,为大家带来第一手新鲜热辣的现 ...