IncreaseClient 中持有一个base,每次调用起increase方法后,返回原先的值,
increase方法自加两次,在check方法中判断返回值和最新值是否相差2.在多线程的环境下就会出错,因为++base不是原子性操作
package com.woxiaoe.study.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 自加类
* @author 小e
*
* 2010-4-24 下午08:39:19
*/
public class IncreaseClient {
private int base = 0;
public IncreaseClient() {
}
public int increase(){
int pre = base;
++ base;
Thread.currentThread().yield();
++ base;
return pre;
}
public boolean check(){
int pre = increase();
System.out.println("pre:" + pre + "\t" + "increase:" + base);
return pre - base == -2?true:false;
}
public static void main(String[] args) {
IncreaseClient ic = new IncreaseClient();
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 10; i++){
exec.execute(new IncreaseChecker(ic));
}
}
}
package com.woxiaoe.study.thread;
/**
* 验证多线程下自加的准确性
* @author 小e
*
* 2010-4-24 下午08:38:14
*/
public class IncreaseChecker extends Thread {
private IncreaseClient ic;
public IncreaseChecker(IncreaseClient ic) {
this.ic = ic;
}
@Override
public void run() {
while(ic.check()){
}
System.out.println(Thread.currentThread() + "自增出错");
System.exit(0);
}
}
解决资源共享的最简单方法极为给会产生冲突的方法加把锁,本例中只需将chenk()方法做如下修改
public synchronized boolean check(){
int pre = increase();
System.out.println("pre:" + pre + "\t" + "increase:" + base);
return increase() - base == -2?true:false;
}
另一种方法是显示的给代码加把锁:
public boolean check(){
lock.lock();
try{
int pre = increase();
System.out.println("pre:" + pre + "\t" + "increase:" + base);
return pre - base == -2?true:false;
}finally{
lock.unlock();
}
}
大体上当使用synchronized关键字时,需要写的代码量更少,并且用户出现的可能性也会降低,因此通常只在解决特殊问题时,才会显示的Lock对象。Lock对象提供了更细粒度的操作。
细节决定成败人的一生会经历很多失败,那如何面对失败,是从容的面对,还是歇斯里的离开?方式很多,结果也会很多,我们可以看下宋孝宗的例子,他的从容离开,给自己点亮了希望的灯光,并因此得道,成为宋孝宗,故事大概如下:故事代码 话说宋高宗没有子嗣,而且近亲一族因为靖康之耻,全部金国带走来,总部来因为没有子嗣导致皇位没有人当吧,...
前言今天看了一篇博客,里面详细介绍了一名Java后端人员的进阶之路,不禁感叹,java之路、任重道远、要学的东西太多太多,想成为大佬需要付出的代价 太大太大,轻者占用自己太多生活的时间,重者头发没了、颈椎弯了、腰间盘突出了、身体不行了、妻子抱怨了…不禁产生疑惑:作为一名程序员,除非对代码对技术无限的热爱,不然以回报与付出相比真的值得么、与付出来说,程序员的工资真的不高,算上加班,时薪真的很低很低了,而且是死工资,没有提成、奖金,没有时间搞副业,尤其是非互联网大厂的程序员、比如说外包人员(crud式程序员)
来自:http://www.cnblogs.com/odoouse/p/5995603.html安装Ubuntu 16,省略 安装时,默认用户名为 odoo ubuntu 16开始 使用 systemd 管理服务,但是systemd 兼容 sysv init 脚本 下载 odoo源码 从 http
点击上方前端Q,关注公众号回复加群,加入前端Q技术交流群前言在线音乐[1]戳我呀!音乐博客源码[2]上线啦!上篇写的想写好面向对象的代码,这篇一定要看 | 重学JS[3]提到的匿名函数提...
【正式发布】火星人敏捷开发手册2012-12-25(基于Scrum的敏捷开发免费培训教材及公司内部宣传材料)
互联网时代,瞬息万变。一个小小的走错,就有可能落后于别人。我们没办法去预测任何行业、任何职业未来十年会怎么样,因为未来谁都不能确定。只能说只要有互联网存在,程序员依然是个高薪热门行业。只要跟随着时代的脚步,学习新的知识。程序员是不可能会消失的,或者说不可能会没钱赚的。我们经常可以听到很多人说,程序员是一个吃青春饭的行当。因为大多数人认为这是一个需要高强度脑力劳动的工种,而30岁、40岁,甚至50...
OpenWrt on VirtualBox环境配置VirtualBox的环境变量配置;wget.exe下载并将其放到git的bin目录下。下载dd工具包。脚本执行环境:windows10 + git bashgit clone https://gitee.com/c4pr1c3/cuc-mis-pptcd cuc-mis-ppt/exp/chap0x01bash setup-vm.sh脚本分析(做了少量修改,可在windows环境中一键安装openwrt)#!/usr/bin
application 应用程式 应用、应用程序application framework 应用程式框架、应用框架 应用程序框架architecture 架构、系统架构 体系结构argument 引数(传给函式的值)。叁见 parameter 叁数、实质叁数、实叁、自变量array 阵列 数组arrow operator arrow(箭头)运算子 箭头操作符ass...
磁盘分区:1、新建磁盘点击编辑虚拟机(注意:需要在关机状态下)——添加硬盘——可以一直点击下一步(注意:磁盘大小可以选择小于20G)2、管理磁盘2.1添加磁盘:见上述方法。2.2管理磁盘三部曲分区:MBR/GRT格式化 文件系统挂载mount1、查看磁盘分区信息(1)方法1:使用命令查看:ll /dev/sd*,可以看出sdb是新建的磁盘,而sda是系统的磁盘。(2)方法2:lsblk:列出块状设备2、创建分区(1)启动分区工具:fdisk /
软硬件环境windows 10 64bitanaconda3 with python 3.7前言编程过程中经常会遇到将float类型数据进行截取,也就是只保留小数点后几位的情况。本文以保留小数点后2位为例,介绍几种常用的实现方法。round方法(base)PSC:\Windows\system32>ipython...
<2012 11 14> Linux V4L2驱动架构解析与开发导引 </h1> <div class="clear"></div> <div class="postBody"> Linux V4L2驱动架构解析与开发导引Andrew按:众所周知,linux中可以采用灵活的多层次的驱动架构来对接口进行统一与抽象,...
2016年11月7日至9日,QCon旧金山大会将重返旧金山渔人码头。此次正值该湾区软件大会10周年,吸引了来自全球的与会者。QCon大会由InfoQ公司组织,致力于为创新者和先行者在软件研发温床城市提供一个分享他们故事的平台,这些城市包括北京、伦敦、纽约、圣保罗、上海、旧金山和东京。\\虽然去年QCon旧金山大会的几乎全部演讲都可在InfoQ.com获取,但我们仍为您在此列出了其中广受欢迎的演讲:...