线程高级应用-心得6-java5线程并发库中同步工具类(synchronizers),新知识大用途
1.新知识普及






2. Semaphore工具类的使用案例
package com.java5.thread.newSkill; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore; /**
* Semaphore工具类的使用案例
* 跟互斥锁有点相似,只是互斥锁只有一把,信号灯可以有多个
* Semaphore:信号灯
*/
public class SemaphoreTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool();
//
final Semaphore sp = new Semaphore(3);
for(int i=0;i<10;i++){
Runnable runnable = new Runnable() { @Override
public void run() {
try {
//acquire:获得;下面方法是获取信号灯
sp.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
//availablePermits():可以获得的许可
System.out.println("线程 "+Thread.currentThread().getName()+" 进入,当前已有 "+(3-sp.availablePermits())+" 个并发!"); try {
Thread.sleep((long)Math.random()*10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程 "+Thread.currentThread().getName()+" 即将离开!");
//释放信号灯
sp.release();
//下面代码有时候执行不准确
System.out.println("线程 "+Thread.currentThread().getName()+" 离开,当前已有 "+(3-sp.availablePermits())+" 个并发!"); }
};
service.execute(runnable);
} }
} /*
* 运行结果:
线程 pool-1-thread-1 进入,当前已有 1 个并发!
线程 pool-1-thread-1 即将离开!
线程 pool-1-thread-1 离开,当前已有 0 个并发!
线程 pool-1-thread-1 进入,当前已有 1 个并发!
线程 pool-1-thread-1 即将离开!
线程 pool-1-thread-1 离开,当前已有 0 个并发!
线程 pool-1-thread-1 进入,当前已有 1 个并发!
线程 pool-1-thread-3 进入,当前已有 2 个并发!
线程 pool-1-thread-1 即将离开!
线程 pool-1-thread-1 离开,当前已有 1 个并发!
线程 pool-1-thread-3 即将离开!
线程 pool-1-thread-3 离开,当前已有 0 个并发!
线程 pool-1-thread-3 进入,当前已有 1 个并发!
线程 pool-1-thread-1 进入,当前已有 2 个并发!
线程 pool-1-thread-3 即将离开!
线程 pool-1-thread-3 离开,当前已有 1 个并发!
线程 pool-1-thread-1 即将离开!
线程 pool-1-thread-1 离开,当前已有 0 个并发!
线程 pool-1-thread-1 进入,当前已有 1 个并发!
线程 pool-1-thread-5 进入,当前已有 2 个并发!
线程 pool-1-thread-1 即将离开!
线程 pool-1-thread-1 离开,当前已有 1 个并发!
线程 pool-1-thread-5 即将离开!
线程 pool-1-thread-5 离开,当前已有 0 个并发!
线程 pool-1-thread-2 进入,当前已有 1 个并发!
线程 pool-1-thread-2 即将离开!
线程 pool-1-thread-2 离开,当前已有 0 个并发!
线程 pool-1-thread-4 进入,当前已有 1 个并发!
线程 pool-1-thread-4 即将离开!
线程 pool-1-thread-4 离开,当前已有 0 个并发! */
3. CyclicBarrier工具类的使用案例
package com.java5.thread.newSkill; import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* CyclicBarrier工具类的使用案例
* 应用场景:各个线程彼此等待,到齐后集体出发
* cyclic:循环的,周期性的
* barrier:障碍物,屏障
*/
public class CyclicBarrierTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3);
for(int i=0;i<3;i++){
Runnable runnable= new Runnable() { @Override
public void run() {
try {
Thread.sleep((long)Math.random()*10000);
//cb.getNumberWaiting()+1;是因为该方法获取的数量是从0开始的
System.out.println("线程 "+ Thread.currentThread().getName()+" 即将到达集合地点1,当前已有 "+(cb.getNumberWaiting()+1)+"已经到达;"+(cb.getNumberWaiting()==2?"都到齐了,继续走啊!":"正在等候!"));
//想在什么地方集合就在什么地方await()等待
cb.await(); Thread.sleep((long)Math.random()*10000);
System.out.println("线程 "+ Thread.currentThread().getName()+" 即将到达集合地点2,当前已有 "+(cb.getNumberWaiting()+1)+"已经到达;"+(cb.getNumberWaiting()==2?"都到齐了,继续走啊!":"正在等候!")); cb.await(); Thread.sleep((long)Math.random()*10000);
System.out.println("线程 "+ Thread.currentThread().getName()+" 即将到达集合地点3,当前已有 "+(cb.getNumberWaiting()+1)+"已经到达;"+(cb.getNumberWaiting()==2?"都到齐了,继续走啊!":"正在等候!")); cb.await();
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
} } /*
* 运行结果:
线程 pool-1-thread-2 即将到达集合地点1,当前已有 1已经到达;正在等候!
线程 pool-1-thread-3 即将到达集合地点1,当前已有 2已经到达;正在等候!
线程 pool-1-thread-1 即将到达集合地点1,当前已有 3已经到达;都到齐了,继续走啊!
线程 pool-1-thread-2 即将到达集合地点2,当前已有 1已经到达;正在等候!
线程 pool-1-thread-1 即将到达集合地点2,当前已有 2已经到达;正在等候!
线程 pool-1-thread-3 即将到达集合地点2,当前已有 3已经到达;都到齐了,继续走啊!
线程 pool-1-thread-3 即将到达集合地点3,当前已有 1已经到达;正在等候!
线程 pool-1-thread-2 即将到达集合地点3,当前已有 2已经到达;正在等候!
线程 pool-1-thread-1 即将到达集合地点3,当前已有 3已经到达;都到齐了,继续走啊!
*/ 4. CountDownLacth工具类的使用案例
package com.java5.thread.newSkill; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* CountDownLacth工具类的使用案例
* 犹如倒计时计数器
* latch:门闩,闩门
* 应用场景:运动员比赛;裁判计时!一款比赛小游戏
* 下面例子:三个线程好比三个运动员,主线程好比一个裁判
*/
public class CountDownLatchTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); //设置一个数量为1的计时器
final CountDownLatch cdOrder = new CountDownLatch(1);
//设置一个数量为3的计时器
final CountDownLatch cdAnswer = new CountDownLatch(3);
for(int i=0;i<3;i++){
Runnable runnable= new Runnable() { @Override
public void run() {
try {
System.out.println("线程 "+ Thread.currentThread().getName()+"正准备接受命令!"); /*开启三个线程,都在这里等待;
* 如何开始下一步呢!?就是再开启一个主线程来用countDown()方法;
* 来进行减数,减到0就可以进行下一步程序
*/
cdOrder.await(); System.out.println("线程 "+ Thread.currentThread().getName()+"已接受命令!");
Thread.sleep((long)Math.random()*10000);
System.out.println("线程 "+ Thread.currentThread().getName()+"回应命令处理结果!"); //countDown();方法就是将计数器身上的计数减1
cdAnswer.countDown(); } catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
try {
Thread.sleep((long)Math.random()*10000);
System.out.println("线程 "+ Thread.currentThread().getName()+"即将发布命令!"); cdOrder.countDown(); System.out.println("线程 "+ Thread.currentThread().getName()+"已发送命令,正在等待结果!"); cdOrder.await(); System.out.println("线程 "+ Thread.currentThread().getName()+"已收到所有响应结果!"); cdAnswer.countDown(); } catch (Exception e) {
e.printStackTrace();
}
service.shutdown();
} }
5. Exchanger工具类的使用案例
package com.java5.thread.newSkill; import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* Exchanger工具类的使用案例
* 应用场景:交易性应用或游戏
* 两个人碰在一起,交换彼此的数据
*/
public class ExchangerTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool();
final Exchanger exchanger = new Exchanger();
service.execute(new Runnable() { @Override
public void run() {
try{ String data1 = "杨凯";
System.out.println("线程 "+Thread.currentThread().getName()+" 正在把数据: "+data1+" 换出去!"); Thread.sleep((long)Math.random()*10000); String data2 = (String) exchanger.exchange(data1);
System.out.println("线程 "+Thread.currentThread().getName()+" 换回的数据为:"+data2);
}catch(Exception e){ }
}
});
service.execute(new Runnable() { @Override
public void run() {
try{ String data1 = "杨旋";
System.out.println("线程 "+Thread.currentThread().getName()+" 正在把数据: "+data1+" 换出去!"); Thread.sleep((long)Math.random()*10000); String data2 = (String) exchanger.exchange(data1);
System.out.println("线程 "+Thread.currentThread().getName()+" 换回的数据为:"+data2);
}catch(Exception e){ }
}
}); } }
线程高级应用-心得6-java5线程并发库中同步工具类(synchronizers),新知识大用途的更多相关文章
- 线程高级应用-心得8-java5线程并发库中同步集合Collections工具类的应用及案例分析
1. HashSet与HashMap的联系与区别? 区别:前者是单列后者是双列,就是hashmap有键有值,hashset只有键: 联系:HashSet的底层就是HashMap,可以参考HashSe ...
- Java中的线程--并发库中的集合
线程中的知识点基本都已经学完了,看看Java5并发库中提供的集合... 一.可堵塞队列 队列包含固定长度的队列和不固定长度的队列 ArrayBlockQueue中只有put()方法和take()方法才 ...
- java 利用同步工具类控制线程
前言 参考来源:<java并发编程实战> 同步工具类:根据工具类的自身状态来协调线程的控制流.通过同步工具类,来协调线程之间的行为. 可见性:在多线程环境下,当某个属性被其他线程修改后,其 ...
- Java核心知识点学习----线程同步工具类,CyclicBarrier学习
线程同步工具类,CyclicBarrier日常开发较少涉及,这里只举一个例子,以做备注.N个人一块出去玩,相约去两个地方,CyclicBarrier的主要作用是等待所有人都汇合了,才往下一站出发. 1 ...
- 《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&并发容器类&同步工具类,消费者模式
上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Has ...
- Java并发(基础知识)——显示锁和同步工具类
显示锁 Lock接口是Java ...
- 并发是个什么鬼之同步工具类CountDownLatch
扯淡 写这篇文章,我先酝酿一下,实不相瞒,脱离底层太久了,更确切的情况是,真没曾认真研究过.就目前来说,很多框架包括工具类已经把实现封装的很深,你只需轻轻的调用一下API,便不费半点力气.以至于大家会 ...
- 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯
1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值 ...
- 线程高级应用-心得4-java5线程并发库介绍,及新技术案例分析
1. java5线程并发库新知识介绍 2.线程并发库案例分析 package com.itcast.family; import java.util.concurrent.ExecutorServi ...
随机推荐
- django 自定义标签和过滤器
django 自定义标签和过滤器 Django支持自定义标签和过滤器.起初还不太重视它这项功能,但最近试了试自定义标签.发现django这个功能实在是太爽了. 首先在你项目的一个app中建立一个pyt ...
- Unity-Animato深入系列---FloatValue阻尼
回到 Animator深入系列总目录 Animator的SetFloat接口可以设置阻尼,并且4种类型变量只有float是支持阻尼的. public void SetFloat(int id, flo ...
- JAVA基础知识之网络编程——-使用MutilcastSocket实现多点广播
IP多点广播原理 设置一组特殊网络地址作为多点广播地址,每一个多点广播地址都被看作一个组,当客户需要发送和接受信息时,加入到该组即可. IP协议为多点广播提供了一批特殊的IP地址,范围是224.0.0 ...
- 局部内部类访问方法中的局部变量为什么加final
转载:http://www.cnblogs.com/mjblogs/p/4971630.html 1)从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形 ...
- HashMap原理详解
HashMap 概述 HashMap 是基于哈希表的 Map 接口的非同步实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.此类不保证映射的顺序,特别是它不保证该顺序恒久不 ...
- 基于PowerShell 3.0的web接口测试
对于web接口测试,做一下总结. 接口测试总结 1. 接口url格式:http://www.xxx.com/a/bbb.html: 2. 接口url后面接的参数格式:“?参数名=参数值&参数名 ...
- Linux的启动过程
Linux的启动过程,也就是Linux的引导流程,这部分主要是理论知识. Linux的开机启动过程 1.1第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的 ...
- c# SendMail
using System; using System.Collections.Generic; using System.Net; using System.Net.Mail; using Syste ...
- 卡尔曼滤波— Constant Velocity Model
假设你开车进入隧道,GPS信号丢失,现在我们要确定汽车在隧道内的位置.汽车的绝对速度可以通过车轮转速计算得到,汽车朝向可以通过yaw rate sensor(A yaw-rate sensor is ...
- CVE-2015-1328(本地提权漏洞)
/* # Exploit Title: ofs.c - overlayfs local root in ubuntu # Date: 2015-06-15 # Exploit Author: rebe ...