线程的synchronized、volatile及原子操作
public class ThreadDemo7{
//structs2线程不安全 共享变量
//n++ 复合操作 对于volatile修饰的变量不安全
//原子操作
int value; //让方法变成一个同步的方法
public synchronized int nextValue(){
return value ++;
}
public static void main(String[] args){
ThreadDemo7 t1 = new ThreadDemo7();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(t1.nextValue() + " " + Thread.currentThread().getName());
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(t1.nextValue() + " " + Thread.currentThread().getName());
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(t1.nextValue() + " " + Thread.currentThread().getName());
}
}
}).start();
}
}
public class ThreadDemo7_1 {
private static volatile int num; //使用countDownLatch来等待使线程执行完
public static CountDownLatch countDownLatch = new CountDownLatch(); //由于n++是复合操作,所以并不能保证线程安全
//public synchronized int NextValue(){
public int NextValue(){
return num ++;
}
public static void main(String[] args){
ThreadDemo7_1 t1 = new ThreadDemo7_1(); for(int i=;i<;i++){
new Thread(new Runnable() {
@Override
public void run() {
for(int j=;j<;j++){
t1.NextValue();
}
countDownLatch.countDown();
}
}).start();
}
try{
countDownLatch.await();
}catch (InterruptedException e){
e.getMessage();
} System.out.println(num);
}
}
public class ThreadDemo7_2 {
private static AtomicInteger num = new AtomicInteger(); //使用countDownLatch来等待使线程执行完
public static CountDownLatch countDownLatch = new CountDownLatch(); public static void main(String[] args){
ThreadDemo7_1 t1 = new ThreadDemo7_1(); for(int i=;i<;i++){
new Thread(new Runnable() {
@Override
public void run() {
for(int j=;j<;j++){
num.incrementAndGet(); //原子性的num++,通过cas方式
}
countDownLatch.countDown();
}
}).start();
}
try{
countDownLatch.await();
}catch (InterruptedException e){
e.getMessage();
} System.out.println(num);
}
概念解析
并发机制依赖于JVM的实现和CPU的指令
1. volatile一般在多线程中使用,保证共享变量的可见性,解决并发带来的问题
可见性意思就是一个线程修改另外一个线程可以看到修改后的值,通过排它锁单独获得这个变量
volatile执行成本低,因为不会引起线程上下文的切换和调度
synchronized是重量级锁
2. volatile深层理解
有volatile变量修饰的共享变量进行读写操作的时候会多出第二行汇编代码
lock前缀的指令在多核处理器下会引发两件事情:
1)lock前缀指令会引起处理器缓存回写到内存
2)这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效
3. synchronized实现同步的基础:java中的每一个对象都可以作为锁
具体表现如下:
1)对于普通同步方法,锁是当前实例对象
2)对于静态同步方法,锁是当前类的class对象
3)对于同步方法块,锁是synchronized括号里配置的对象
当一个线程视图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁
Synchronized在JVM里的实现原理:JVM基于进入和退出Monitor对象来实现方法同步和代码块同步
2. 无锁,偏向锁,轻量级锁,重量级锁
线程的synchronized、volatile及原子操作的更多相关文章
- java线程安全— synchronized和volatile
java线程安全— synchronized和volatile package threadsafe; public class TranditionalThreadSynchronized { pu ...
- 线程执行synchronized同步代码块时再次重入该锁过程中抛异常,是否会释放锁
一个线程执行synchronized同步代码时,再次重入该锁过程中,如果抛出异常,会释放锁吗? 如果锁的计数器为1,抛出异常,会直接释放锁: 那如果锁的计数器为2,抛出异常,会直接释放锁吗? 来简单测 ...
- synchronized + volatile + ThreadLocal
线程的共享 synchronized + volatile + ThreadLocal <1> synchronized 锁住的是对象,当用它来锁住一个类时,实际上也是锁的一个对象. ...
- synchronized&volatile
synchronized(JVM实现的锁) 通过这两个关键字,我们可以很容易的实现同步多个任务的行为,可以实现同一时刻,只能有一条线程去访问共享资源 一: 修饰普通方法 多个线程,共同去竞争访问,方法 ...
- Java线程同步synchronized的理解
JVM中(留神:马上讲到的这两个存储区只在JVM内部与物理存储区无关)存在一个主内存(Main Memory),Java中所有的变量存储在主内存中,所有实例和实例的字段都在此区域,对于所有的线程是共享 ...
- 对象、对象监视器、同步队列、执行线程关系(synchronized的实现细节或原理)
synchronized在使用的时候底层细节你了解吗,相信很多同学对细节很少关注:比如竞争失败了的线程怎么安置,每个对象的监视器,线程执行synchronized时,其实是获取对象的监视器才能进入同步 ...
- java并发:线程同步机制之Volatile关键字&原子操作Atomic
volatile关键字 volatile是一个特殊的修饰符,只有成员变量才能使用它,与Synchronized及ReentrantLock等提供的互斥相比,Synchronized保证了Synchro ...
- Java线程(二):线程同步synchronized和volatile
上篇通过一个简单的例子说明了线程安全与不安全,在例子中不安全的情况下输出的结果恰好是逐个递增的(其实是巧合,多运行几次,会产生不同的输出结果),为什么会产生这样的结果呢,因为建立的Count对象是线程 ...
- 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition
img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...
随机推荐
- ngx-moment汉化
1.导入汉化文件 import '../../../node_modules/moment/locale/zh-cn.js' 2.使用汉化 <span>{{item.time|amLoca ...
- (网页)css和js的版本号问题
HTML页面自动清理js.css文件的缓存,之前用的是?v=11每次都要找寻到网页进行更改,非常的麻烦. <script type="text/javascript"> ...
- (网页)angularJs中怎么模拟jQuery中的this?(转)
转载自mini_fan博客园: 今天想在Angular项目中使用jQuery的this功能,发现undefined.代码如下: HTML部分: <p ng-click="testCli ...
- Windows桌面或服务器环境下嵌入JavaScript支持(JSRT)
很多人比较关注Google的JS V8 JavaScript引擎,确实Google最近很高调.但这个库在Windows下使用确实有点难度,即使在Linux嵌入,也需要下载gyp,编译安装,然后再下载v ...
- Docker Data Center系列(三)- DTR安装指南
本系列文章演示如何搭建一个mini的云平台和DevOps实践环境. 基于这套实践环境,可以部署微服务架构的应用栈,演练提升DevOps实践能力. 1 系统要求 1.1 硬件和软件要求 成为UCP管理的 ...
- linux(centos)无中文输入,如何解决
1.终端执行安装命令 yum install "@Chinese Support" 2.如下图,多出Input method 3.点击进行配置 4.reboot重启系统,新建一个文 ...
- HTTP Authentication
PS:近期看了一本思维导图的书,实践一下.
- python之bytes和string
转自:https://www.cnblogs.com/skiler/p/6687337.html 1.bytes主要是给在计算机看的,string主要是给人看的 2.中间有个桥梁就是编码规则,现在大趋 ...
- 排序算法之折半插入排序的思想以及Java实现
1 基本思想 折半插入排序(binary insertion sort)的基本原理与直接插入排序相同,不同之处在于,确定当前记录在前面有序子数组中的位置时,直接插入排序是采用顺序查找的方法,而折半插入 ...
- Java的基础知识四
一.Java 流(Stream).文件(File)和IO Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基 ...