[Java Concurrent] 并发访问共享资源的简单案例
EvenGenerator 是一个偶数生成器,每调用一个 next() 就会加 2 并返回叠加后结果。在本案例中,充当被共享的资源。
EvenChecker 实现了 Runnable 接口,可以启动新的线程执行 run() 任务,用于检测所指向的偶数生成器是否每次都返回偶数值。
EvenCheckerThreadDemo 用于演示多线程下的执行情况。
非线性安全版本
EvenGenerator, 偶数生成器,每调用一个 next() 就会加 2 并返回叠加后结果。
这里的 next() 方法并非线性安全,在多线程同时访问时,可能会返回奇数。一个线程执行了第一个累加语句后,被调度器中断,替换上下文,另一个进程开始执行 next() 方法,则会返回奇数。
public class EvenGenerator {
private int count = 0;
public int next(){
count++;
count++;
return count;
}
}
EvenChecker 检测指向的 EvenGenerator 是不是每次都返回偶数。
public class EvenChecker implements Runnable {
private EvenGenerator eg;
private final int id = count++;
private static int count = 0;
@Override
public void run() {
while (true){
int res = eg.next();
if (res % 2 != 0){
System.out.println("not even" + res + " | Thread # " + id);
break;
}
}
}
public EvenChecker(EvenGenerator eg){
this.eg = eg;
}
}
演示多线程下的执行情况,多个线程同时执行 EvenChecker ,但是引用的是同一个 EvenGenerator
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class EvenCheckerThreadDemo { public static void main(){
ExecutorService exec = Executors.newCachedThreadPool(); EvenGenerator eg = new EvenGenerator(); for (int i = 0; i< 5 ; i++){
exec.execute(new EvenChecker(eg));
}
}
}
线性安全版本1
使用 synchronized 关键词,使得 next() 方法线程安全,确保同一时间内,最多只有一个线程进入该方法。
public class EvenGenerator {
private int count = 0;
public synchronized int next(){
count++;
count++;
return count;
}
}
线性安全版本2
使用 Lock 把访问、修改共享变量的语句进行同步,确保同一时间内,最多只有一个线程进入该块代码。使用 try-finally 结构,可以确保 Lock 一定被释放。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class EvenGenerator { private int count = 0; private Lock lock = new ReentrantLock(); public int next(){
lock.lock();
try {
count++;
count++;
return count;
} finally{
lock.unlock();
}
}
}
参考资料
Page 827, Resolving shared resource contention, Thinking in Java
[Java Concurrent] 并发访问共享资源的简单案例的更多相关文章
- 多线程同步与并发访问共享资源工具—Lock、Monitor、Mutex、Semaphore
“线程同步”的含义 当一个进程启动了多个线程时,如果需要控制这些线程的推进顺序(比如A线程必须等待B和C线程执行完毕之后才能继续执行),则称这些线程需要进行“线程同步(thread synchro ...
- java concurrent 并发多线程
Concurrent 包结构 ■ Concurrent 包整体类图 ■ Concurrent包实现机制 综述: 在整个并发包设计上,Doug Lea大师采用了3.1 Concurrent包整体架构的三 ...
- java Concurrent并发容器类 小结
Java1.5提供了多种并发容器类来改进同步容器的性能. 同步容器将所有对容器的访问都串行化,以实现他们的线程安全性.这种方法的代价是严重降低并发性,当多个线程竞争容器的锁时,吞吐量将严重减低. 一 ...
- java基础之多线程四:简单案例
多线程案例: 有一个包包的数量为100个,分别从实体店和官网进行售卖.使用多线程的方式,分别打印实体店和官网卖出包包的信息.分别统计官网和实体店各卖出了多少个包包 第一种方法 继承Thread类: p ...
- java concurrent 中ExecutorService和CompletionService简单区别
举个例子,现在需要执行10个任务,这些任务都是有返回值,并且需要使用10个线程同时执行.一般的做法就是创建ExecutorService线程池,pool大小10,每个任务实现Callable接口,然后 ...
- Java精通并发-wait与notify方法案例剖析与详解
在上一节中对Object的wait.notify.notifyAll方法进行了总结,这次举一个具体案例来进行巩固,题目如下: 编写一个多线程程序,实现这样的一个目标: 1.存在一个对象,该对象有一个i ...
- java高并发系列 - 第15天:JUC中的Semaphore,最简单的限流工具类,必备技能
这是java高并发系列第15篇文章 Semaphore(信号量)为多线程协作提供了更为强大的控制方法,前面的文章中我们学了synchronized和重入锁ReentrantLock,这2种锁一次都只能 ...
- java多线程(五)-访问共享资源以及加锁机制(synchronized,lock,voliate)
对于单线程的顺序编程而言,每次只做一件事情,其享有的资源不会产生什么冲突,但是对于多线程编程,这就是一个重要问题了,比如打印机的打印工作,如果两个线程都同时进行打印工作,那这就会产生混乱了.再比如说, ...
- OAF_开发系列27_实现OAF中Java类型并发程式开发调用XML Publisher(案例)
20150814 Created By BaoXinjian
随机推荐
- 图片标签的alt与title区别
一.img标签alt属性 1.alt属性是考虑到不支持图像显示或者图像显示被关闭的浏览器的用户,以及视觉障碍的用户和使用屏幕阅读器的用户.当图片不显示的时候,图片的替换文字. 2.alt属性值得长度必 ...
- 兼容所有浏览器的JQuery zClip插件实现复制到剪贴板功能
相信这个功能大家平时上网经常能碰到,以前也没怎么留意怎么实现的,直到项目中需要. 网上一搜一大堆,单纯使用js方法也不是没有,但是由于各浏览器的安全机制不同,不是跨浏览器的.去看了几个常用的网站,都是 ...
- Java编程思想-泛型-简单泛型例子
基本类型无法做为类型参数 代码如下: /** * */ package test.thinkinjava.Generics; import java.util.ArrayList; import ja ...
- iOS 中Window优先级的问题
在项目中,视频播放时候遇到网络切换需要弹出AlertView提醒用户,忽然发现转屏的时候播放View加到KeyWindow的时候把AleryView挡住了.如图 因为转屏的时候视图是直接加载到 [UI ...
- (转)xcode报Could not find a storyboard named...错误的解决办法
首先确定是否有用到storyboard 如果没有用到的话,需要将涉及到storyboard的地方修改: 1 删除plist文件里的设置 2 修改程序中使用到storyboard的地方 如果确实有使用s ...
- angularjs中ng-repeat-start与ng-repeat-end用法实例
<!DOCTYPE html> <html lang="zh-CN" ng-app="app"> <head> <me ...
- POJ3185 The Water Bowls(反转法or dfs 爆搜)
POJ3185 The Water Bowls 题目大意: 奶牛有20只碗摆成一排,用鼻子顶某只碗的话,包括左右两只在内的一共三只碗会反向,现在给出碗的初始状态,问至少要用鼻子顶多少次才能使所有碗都朝 ...
- python3 解析apk图标
有两处值小点,一是如何解压缩,另一个是如何写文件,第二点上我找的是phthon2的代码,一直写文件的时候报不是字符串的问题,将打开方式加上"b“的模式搞定 print文件出来直接删除了,原因 ...
- CentOS7 开启关闭网卡
ifdown ifcfg-enp7s0 关闭网卡 ifup ifcfg-enp7s0 开启网卡
- jquery 工作空间注册
在一些面向对象的语言中有命名空间的概念,好处就是把不同的类放在不同的文件夹下面,这样就不会发生命名冲突,当然命名空间还有其他的作用. 在这里我们讨论的是在JS中怎么使用命名空间.当然JS并没有提供原生 ...