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变量只能保证可见性.所以,在不需要原子性的时候,可以用它.
JAVA-线程安全性的更多相关文章
- Java线程安全性中的对象发布和逸出
发布(Publish)和逸出(Escape)这两个概念倒是第一次听说,不过它在实际当中却十分常见,这和Java并发编程的线程安全性就很大的关系. 什么是发布?简单来说就是提供一个对象的引用给作用域之外 ...
- Java并发编程(五):Java线程安全性中的对象发布和逸出
发布(Publish)和逸出(Escape)这两个概念倒是第一次听说,不过它在实际当中却十分常见,这和Java并发编程的线程安全性就很大的关系. 什么是发布?简单来说就是提供一个对象的引用给作用域之外 ...
- Java线程安全性-原子性工具对比
synchronized 不可中断锁,适合竞争不激烈的场景,可读性好,竞争激烈时性能下降很快 Lock 可中断锁,多样化同步,竞争激烈时能维持常态 Atomic 竞争激烈时能维持常态,比Lock性能还 ...
- Java并发编程学习笔记(一)——线程安全性
主要概念:线程安全性.原子性.原子变量.原子操作.竟态条件.复合操作.加锁机制.重入.活跃性与性能. 1.当多个线程访问某个状态变量并且其中有一个线程执行写入操作时,必须采用同步机制来协同这些线程对变 ...
- 《Java并发编程实战》第二章 线程安全性 读书笔记
一.什么是线程安全性 编写线程安全的代码 核心在于要对状态訪问操作进行管理. 共享,可变的状态的訪问 - 前者表示多个线程訪问, 后者声明周期内发生改变. 线程安全性 核心概念是正确性.某个类的行为与 ...
- JAVA并发编程实战---第二章:线程安全性
对象的状态是指存储在状态变量中的数据.对象的状态可能包括其他依赖对象的域.例如HashMap的状态不仅存储在HashMap本身,还存储在许多Map.Entry对象中.对象的状态中包含了任何可能影响其外 ...
- Java 并发基础——线程安全性
当线程安全:多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协调,这个类都能表现出正确的行为,那么久称这个类是线程安全的. 在线程 ...
- Java并发编程实战 之 线程安全性
1.什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何种调用方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全 ...
- Java并发-线程安全性
首先了解一下多线程的概念 多线程:两段或以上的代码同时进行,多个顺序执行流. 并发和并行的区别 并发:做一下这个做一下那个. 并行:同时进行. 线程和进程的区别 进程:资源分配的基本单位,运行中的程序 ...
- 【Java并发.2】线程安全性
要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享(Shared)和可变的(Mutable)状态的访问. “共享”意味着变量可以由多个线程同时访问,而“可变”则意味着变量的值在其生 ...
随机推荐
- ELK之nginx日志分析图表创建
一.kibana面板介绍 Discover:查询数据Visualize:统计图表Dashboard:显示面板,添加相应的图表在面板中Settings:创建索引 二.图表创建 1.饼图创建 以创建一个状 ...
- RIDE常用快捷键
重命名: F2 搜索关键字: F5 执行用例: F8 创建新工程: Ctrl+N 创建新测试套: Ctrl+Shift+F 创建新用例: Ctrl+Shift+T 创建新关键字: Ctrl+Shift ...
- HDOJ/HDU 2565 放大的X(分段思考~)
Problem Description 请你编程画一个放大的'X'. 如3*3的'X'应如下所示: X X XX X5*5的'X'如下所示:X X X X X X XX X Input 输入数据第一行 ...
- HDOJ/HDU 1251 统计难题(字典树啥的~Map水过)
Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己 ...
- numpy note_1
tile(A,reps) 通过重复 reps次数的A 创建一个数组 examples: >>> a = np.array([0, 1, 2]) >>> np.til ...
- Bzoj 1975: [Sdoi2010]魔法猪学院 dijkstra,堆,A*,K短路
1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1357 Solved: 446[Submit][Statu ...
- WPP
WPP(Wavefront Parallel Processing) 上一行的第二个LCU处理完毕,即对当前行的第一个LCU的熵编码(CABAC)概率状态参数进行初始化,如图5所示.因此,只需要上一行 ...
- 基于TCP协议的服务器(多线程)
import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; impo ...
- python Day 1 - 搭建开发环境
搭建开发环境 首先,确认系统安装的Python版本是2.7.x: $ python --version Python 2.7.5 然后,安装开发Web App需要的第三方库: 前端模板引擎jinja2 ...
- 让你的Xcode8 支持 iOS7
Xcode8 发布,更新后,发现支持从iOS8开始,可是公司要求从iOS7开始,,,这和苹果相悖. 不过没关系. 跳转 www.cnblogs.com/starainDou/p/5325643.htm ...