1.Exchanger

功能:用于线程间数据的交换

应用场景:1)遗传算法,目前还不是特别理解  2)校对工作,假设A,B线程做同一件任务,可以通过数据校验判断两线程是否正确的工作

例子:是一个简单的校对工作例子

public class TestExchanger {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
ExecutorService es = Executors.newFixedThreadPool(2); //拥有两个线程的线程池
es.execute(new Runnable() {
@Override
public void run() {
String A = "银行流水A";
try {
exchanger.exchange(A);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}); es.execute(new Runnable() {
@Override
public void run() {
String B = "银行流水B";
try {
String A = exchanger.exchange(B);
System.out.println("A和B数据是否一致: " + A.equals(B) + ",A: " + A + ",B: " + B);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}

Exchanger类中最重要的一个方法就是exchange(),该方法用于交换信息,并且接受来自另外一个线程的数据,exchange()方法里面还可以加参数。exchange(V x,long timeout,TimeUnit unit)设置一个最大等待时间避免一直等待

注意:信息交换是在同步点(Exchager提供一个同步点)进行交换,而不是两个线程调用了exchange()方法就进行交换。

底层实现:Lock+Condition,暂时还没深入,学习了进行补充

2.Semaphore

功能:控制同时访问特定资源的线程数量

应用场景:流量控制,比如数据库的连接

例子:

public class TestSemaphore {
public static void main(String[] args) {
// 线程池
ExecutorService exec = Executors.newCachedThreadPool();
//一次只能5个线程同时访问
final Semaphore semp = new Semaphore(5);
// 模拟20个客户端访问
for (int index = 0; index < 20; index++) {
final int NO = index;
Runnable run = new Runnable() {
public void run() {
try {
// 获取许可
semp.acquire();
System.out.println("Accessing: " + NO);
Thread.sleep((long) (Math.random() * 10000));
// 访问完后,释放
semp.release();
System.out.println("-----------------"+semp.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
} } };
exec.execute(run);
} // 退出线程池
exec.shutdown(); }
}

同时有五个线程可以执行,获取资源后打印语句后随机睡眠,最后释放资源,semp.availablePermits(),可以获得的许可数量,释放一个后将有一个没有被分发的许可证,当有多的许可证时,会采取先到先得的方式分配许可

Semaphore有两个构造函数,Semaphore(int)和Semaphore(int,boolean)。参数中的int表示该信号量拥有的许可数量,boolean表示获取许可的时候是否是公平的,如果是公平的那么,当有多个线程要获取许可时,会按照线程来的先后顺序分配许可,否则,线程获得许可的顺序是不定的

3.CyclicBarrier

功能:控制同时访问特定资源的线程数量

应用场景:希望创建一组任务,并行执行,在进行下一个步骤之前等待,直到所有任务完成

例子:赛马比赛。只有当所有马一起到达栅栏时,才能继续跑下一个栅栏

Horse类:

public class Horse implements Runnable {
private static int counter = 0;
private final int id = counter++;
private int strides = 0;
private static Random rand = new Random(47);
private static CyclicBarrier barrier;
public Horse(CyclicBarrier b) { barrier = b; }
public synchronized int getStrides() { return strides; }
public void run() {
try {
while(!Thread.interrupted()) {
synchronized(this) {
strides += rand.nextInt(3); // Produces 0, 1 or 2
}
barrier.await(); //在栅栏处等待
}
} catch(InterruptedException e) {
// A legitimate way to exit
} catch(BrokenBarrierException e) {
// This one we want to know about
throw new RuntimeException(e);
}
}
public String toString() { return "Horse " + id + " "; }
public String tracks() {
StringBuilder s = new StringBuilder();
for(int i = 0; i < getStrides(); i++)
s.append("*");
s.append(id);
return s.toString();
}
}

HorseRace类:

public class HorseRace {
static final int FINISH_LINE = 75;
private List<Horse> horses = new ArrayList<Horse>();
private ExecutorService exec =
Executors.newCachedThreadPool();
private CyclicBarrier barrier;
public HorseRace(int nHorses, final int pause) {
barrier = new CyclicBarrier(nHorses, new Runnable() {
public void run() {
System.out.println("执行runnable方法的线程: " + Thread.currentThread().getName());
StringBuilder s = new StringBuilder();
for(int i = 0; i < FINISH_LINE; i++)
s.append("="); // The fence on the racetrack
System.out.println(s);
for(Horse horse : horses)
System.out.println(horse.tracks());
for(Horse horse : horses)
if(horse.getStrides() >= FINISH_LINE) {
System.out.println(horse + "won!");
exec.shutdownNow();
return;
}
try {
TimeUnit.MILLISECONDS.sleep(pause);
} catch(InterruptedException e) {
System.out.println("barrier-action sleep interrupted");
}
}
}); for(int i = 0; i < nHorses; i++) {
Horse horse = new Horse(barrier);
horses.add(horse);
exec.execute(horse);
}
} public static void main(String[] args) {
int nHorses = 7;
int pause = 200; new HorseRace(nHorses, pause);
}
}

CyclicBarrier有两个构造函数:

public CyclicBarrier(int parties, Runnable barrierAction) {}
public CyclicBarrier(int parties) {}

parties代表一次要并行执行的任务,barrierAction当这些线程都到达barries状态时要执行的任务,会选择一个线程去启动这个任务

重载方法await()

public int await() throws InterruptedException, BrokenBarrierException { }
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { }

第一个方法用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务。第二个方法是让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务

4.CountDownLatch

功能:允许一个或多个线程等待其他线程完成操作

应用场景:

例子:

public class TestCountDown {
private static CountDownLatch c = new CountDownLatch(2); //等待线程的执行数量为2
public static void main(String[] args) throws InterruptedException {
new Thread(
new Runnable() {
@Override
public void run() {
System.out.println(1);
c.countDown();
}
}
).start(); new Thread(new Runnable() {
@Override
public void run() {
System.out.println(2);
c.countDown();
}
}).start(); c.await(); //阻塞当前线程,即main线程等待其他线程完成任务以后才能执行
System.out.println(3);
} }

java并发包下的并发工具类的更多相关文章

  1. Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger

    在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...

  2. 【Java并发工具类】Java并发容器

    前言 Java并发包有很大一部分都是关于并发容器的.Java在5.0版本之前线程安全的容器称之为同步容器.同步容器实现线程安全的方式:是将每个公有方法都使用synchronized修饰,保证每次只有一 ...

  3. 【Java并发工具类】Semaphore

    前言 1965年,荷兰计算机科学家Dijkstra提出的信号量机制成为一种高效的进程同步机制.这之后的15年,信号量一直都是并发编程领域的终结者.1980年,管程被提出,成为继信号量之后的在并发编程领 ...

  4. Java并发编程-并发工具类及线程池

    JUC中提供了几个比较常用的并发工具类,比如CountDownLatch.CyclicBarrier.Semaphore. CountDownLatch: countdownlatch是一个同步工具类 ...

  5. Java并发—并发工具类

    在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程 ...

  6. JAVA并发工具类---------------(CountDownLatch和CyclicBarrier)

    CountDownLatch是什么 CountDownLatch,英文翻译为倒计时锁存器,是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 闭锁可以延迟线程的进 ...

  7. 《Java并发编程的艺术》第6/7/8章 Java并发容器与框架/13个原子操作/并发工具类

    第6章 Java并发容器和框架 6.1  ConcurrentHashMap(线程安全的HashMap.锁分段技术) 6.1.1 为什么要使用ConcurrentHashMap 在并发编程中使用Has ...

  8. java多线程10:并发工具类CountDownLatch、CyclicBarrier和Semaphore

    在JDK的并发包(java.util.concurrent下)中给开发者提供了几个非常有用的并发工具类,让用户不需要再去关心如何在并发场景下写出同时兼顾线程安全性与高效率的代码. 本文分别介绍Coun ...

  9. java 并发工具类CountDownLatch & CyclicBarrier

    一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...

随机推荐

  1. Mysql数据库之auto_increment

    一.概述 在数据库应用中,我们经常需要用到自动递增的唯一编号来标识记录.在MySQL中,可通过数据列的auto_increment属性来自动生成.可在建表时可用“auto_increment=n”选项 ...

  2. java:利用静态字段和构造函数实现已建对象数查询

    问题:使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数. 请写一个类,在任何时候都可以向它查询"你已经创建了多少个对象?". 程序设计思想: 利用静态变量指定一个计数 ...

  3. MongoDB全文检索

    1. 全文检索概念: 全文检索是对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式.  (暂时不支持中文) ...

  4. fastDFS文件服务器迁移

    在实际的项目应用中,由于服务器替换或项目变更难免会存在fastDFS文件服务器迁移的工作.本文重点介绍fastDFS文件系统在不同情况下的文件迁移处理方案. 1.迁移时IP地址不变 通过文件服务器存储 ...

  5. Java基础笔记10

    类的设计分析: 1.根据需求抽取属性.(名词几乎都是属性) 2.属性私有化(private) 3.生成setter和getter方法 4.可以根据需要添加构造函数. 5.根据需求抽取其他方法.(动词几 ...

  6. angular核心$watch,$digest,$apply之间的联系

    浏览器事件发生时,会在浏览器的上下文window中执行,而angular有自己的上下文angular content,angular 事件在自己的上下文angular content中执行. $wat ...

  7. IIS下自定义错误页面配置的两种方式(亲测可行)--IIS服务器

    网站自定义错误页面的设置,大家应该都知道它的重要性……不多说,下面带大家一步步在IIS下设置网站自定义错误页面…… 1.首先进入你的网站主页,找到[错误页](注意是IIS下的错误页不是.NET错误页) ...

  8. 通过对DAO层的封装减少数据库操作的代码量

     在学框架之前,写项目时总是要花大量的时间去写数据库操作层代码,这样会大大降低我们的效率,为了解决这个问题,我花了两天时间利用反射机制和泛型将DAO层进行了封装,这样我们只需要写sql语句,不需要再写 ...

  9. SeaJS之shim插件:解决非cmd规范的插件与sea的区别

    SeaJS 中的模块默认都遵守 CMD 规范,但现实中已存在大量普通 JavaScript 类库,比如 jQuery.Underscore 等.使用 shim 插件,可以将这些普通 JS 文件转换成 ...

  10. 深入分析Android动画(二)

    上回书说到Android动画的分类以及基本使用,这会书主要说Android属性动画的原理,对于View动画的原理本篇不做深入分析.对于Android动画的基础请看深入分析Android动画(一) 我们 ...