JAVA-线程安全性
每个锁关联一个请求计数和一个占有它的线程.当计数为0时,表示该锁未被占有.此时线程请求时,JVM将记录锁的占有线程,并将请求计数加1.如果同一线
程再次请求这个锁,计数再加1.每次退出synchronized 标识的块时计数会减1.当计数为0时,锁被释放.
会影响性能.所以我们最好是将一些需要同步的原子操作放在同步块中.如下面这种做法:
synchronized (this) {
++hits;
if (i.equals(lastNumber)) {
++cacheHits;
factors = lastFactors.clone();
}
}
if (factors == null) {
factors = factor(i);
synchronized (this) {
lastNumber = i;
lastFactors = factors.clone();
}
}
块中都只有很简短的代码.第一个块保护着检查再运行的操作以检查对我们很重要的状态码,另一个进行数据的更新.
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready)
Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
}
上面的mian主线程运行时还充当了"写线程",并且新建"读线程"并让它运行.读线程会不断的循环直到ready的值为true.但在有些情况下,上面的程序会和我们想象的输入42相异:
由于JAVA的"重排序"机制(JVM:只要代码顺序改变对结果不产生影响,那么就不能保证代码执行的顺序是书写的顺序)可能在对number设置值前ready的值就已经是true了.那么输入的结果会是0.
后可以解决这一问题.
等64位的数据则被做为两个32位数进行运算.
test;
类型后,编译器与运行时会监视这个变量,而且对它的操作不会与其他的内在操作重排序.它不会缓存在寄存器或者缓存在其它地方,所以读一个volatile
类型的变量时,它总是返回由某一线程所写入的最新值.我们可以将它看做轻量级的同步机制.
private int value;
public synchronized int get() {
return value;
}
public synchronized void set(int value) {
this.value = value;
}
如上代码可以被:volatile private int
value;以及不加同步声明的getter,setter方法所代替.但当然会牺少许功能:加锁可以保证可见性和原子性,但volatile变量只能保证可见性.所以,在不需要原子性的时候,可以用它.
最新文章
- pywin32 创建一个窗口
- 基于dom的xss漏洞原理
- [Linux] Nginx networking 403 Forbidden 静态文件不允许查看
- Java基础之在窗口中绘图——渐变填充(GradientApplet 1)
- [ubuntu14.04 amd64 ]搜狗拼音輸入法安裝
- 如何用nodejs写入mysql 的blob格式的数据
- NFC(10)NDEF uri格式规范及读写示例(解析与封装ndef uri)
- 经典算法题每日演练——第十一题 Bitmap算法
- hibernate 事务理解
- 201621123062《java程序设计》第九周作业总结
- Java中的静态方法和实例方法的调用的理解(不同的类下的方法调用)
- Fiddler 你需要了解的
- [转].Python中sorted函数的用法
- C#导出Excel文件,过长数值显示为科学计数法解决方法 C#
- Hive QL的操作
- @RequestParam注解一般用法
- e802. 创建一个位置大小的JProgressBar组件
- videojs IE8无法播放解决方案
- tty命令详解
- Python实现类似JavaScript 的Json对象
热门文章
- 畅通工程 HDOJ--1863
- ATL ActiveX 非管理员权限发布(支持vs2005)
- HDOJ/HDU 2565 放大的X(分段思考~)
- nodejs 基本问题答疑
- Dijkstra算法求解最短路径分析
- 普通Windows控制台窗口运行nmake编译VC
- Junit初体验
- PHP的curl实现get,post 和 cookie(实例)
- Can't connect to MySQL server on localhost (10061)解决方法
- 闪回还原点(Flashback Restore Point)