线程的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并发编程中必须要理解的一个知识点.其实使用起来还是比 ...
随机推荐
- Windows 10文件夹Shirt+鼠标右键出现“在此处打开命令窗口”
Windows 10文件夹Shirt+鼠标右键出现“在此处打开命令窗口” Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Directo ...
- Android Touch事件传递机制 二:单纯的(伪生命周期) 这个清楚一点
转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...
- Android项目实战(五十一):浅谈GreenDao
比较出名的数据库框架 GreenDao使用步骤: 1.app目录下的build.gradle文件 添加依赖 compile 'org.greenrobot:greendao:3.2.0' 顶部添加插件 ...
- java方法中把对象置null,到底能不能加速垃圾回收
今天逛脉脉,看见匿名区有人说java中把对做置null,这种做法很菜,不能加速垃圾回收,但是我看到就觉得呵呵了,我是觉得可以加速置null对象回收的. 测试的过程中,费劲的是要指定一个合理的测试堆大小 ...
- 解决OpenCV JavaCameraView相机preview方向问题
网上找了很多解决都是有问题的,研究了半天源码解决了这个问题.我是从整个相机启动和数据传输的过程着手的,这里捡重点介绍一下,最后会贴上修改后的两个源文件. 首先要知道一个概念. 图里的小圆圈是Home按 ...
- python ddt
#!/usr/bin/env/python # -*- coding: utf-8 -*- # @Time : 2018/12/15 15:27 # @Author : ChenAdong # @Em ...
- 移动Web前端,游客点击商品的收藏按钮,登录完成,回来之后,如何自动收藏
我们都知道,移动Web端(M站环境下),很多时候,前端是无法判断用户的登录状态的,因为出于安全性考虑,与账号相关的cookie字段一般都是 http-only的. 如果前端想判断用户的登录状态,需要主 ...
- Linux中DNS的设置
1.查看本机的域名 hostname 2.修改DNS 临时修改: hostname desktop0.example.com 永久修改: hostnamectl set-hostname deskto ...
- 初学ubuntu命令
将我第一天学的内容做个笔记 ,方便日后查看 命令的使用: ls ls -a 显示所有文件 ls -l 显示文件的所有信息 cp 注意命令格式 /home/../temp/a /ho ...
- 浏览器本地数据存储解决方案以及cookie的坑
本地数据存储解决方案以及cookie的坑 问题: cookie过长导致页面打开失败 背景: 在公司的项目中有一个需求是打开多个工单即在同一个页面中打开了多个tab(iframe),但是需要在刷新时只刷 ...