分析volatile关键字可以从这三个方面分析,什么是程序的原子性,什么是程序的可见性,什么是程序的有序性

什么是程序的原子性

以下语句那些是原子操作?

public class ThreadCounter implements Runnable {
private int count = 0;
@Override
public void run() {
++count;
// count++;
}
public static void main(String[] args) throws InterruptedException {
ThreadCounter thread = new ThreadCounter();
for(int i = 0; i< 10000; i++){
new Thread(thread).start();
}
Thread.sleep(1000);//确保线程执行完
System.out.println(thread.count);
}
}

演示结果:语句一和二是非原子操作,语句三和四是原子操作

执行指令:javap -s -c ThreadCounter
run方法的指令码(count++):
 
count++这行代码分成了4个指令来执行,在多线程的情况下会不一致。

解决方法:

public class ThreadCounter implements Runnable {
private int count = 0;
@Override
public void run() {
synchronized (this) {
++count;
// count++;
}
}
public static void main(String[] args) throws InterruptedException {
ThreadCounter thread = new ThreadCounter();
for(int i = 0; i< 10000; i++){
new Thread(thread).start();
}
Thread.sleep(1000);//确保线程执行完
System.out.println(thread.count);
}
}

什么是程序的可见性?

public class VolatileExample {
boolean v =false; private void write(){
v =true;
} private void read(){
while(!v){
}
System.out.println("程序结束!");
} public static void main(String[] args) throws InterruptedException {
final VolatileExample example = new VolatileExample();
Thread thread1 = new Thread(()->{example.read();});
thread1.start();
Thread.sleep(1000);
Thread thread2 = new Thread(()->{example.write();});
thread2.start();
}
}
演示结果:
    程序没有结束,read方法中的v没有因write方法的修改而退出循环!
解决方法:为变量v添加volatile关键字
public class VolatileExample {
volatile boolean v =false; private void write(){
v =true;
} private void read(){
while(!v){
}
System.out.println("程序结束!");
} public static void main(String[] args) throws InterruptedException {
final VolatileExample example = new VolatileExample();
Thread thread1 = new Thread(()->{example.read();});
thread1.start();
Thread.sleep(1000);
Thread thread2 = new Thread(()->{example.write();});
thread2.start();
}
}

什么是程序的有序性?

Volatile应用场景

 1. 状态标记量 

public class ThreadTest {
private volatile boolean isContinue = false; private class HandleThread extends Thread {
@Override
public void run() {
while (isContinue) {
// do something
}
};
}
}

2. double check

 

总结:

volatile在可见性和有序性可以起到作用,但是不能保证原子性,是一种弱同步。

synchronized可以保证原子性,可见性,一致性,是一种强同步。

 
 
 
 
 
 
 
 
 

Java多线程技术-Volatile关键字解析的更多相关文章

  1. Java并发编程 Volatile关键字解析

    volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了 ...

  2. Java 并发:volatile 关键字解析

    摘要: 在 Java 并发编程中,要想使并发程序能够正确地执行,必须要保证三条原则,即:原子性.可见性和有序性.只要有一条原则没有被保证,就有可能会导致程序运行不正确.volatile关键字 被用来保 ...

  3. java并发系列(六)-----Java并发:volatile关键字解析

    在 Java 并发编程中,要想使并发程序能够正确地执行,必须要保证三条原则,即:原子性.可见性和有序性.只要有一条原则没有被保证,就有可能会导致程序运行不正确.volatile关键字 被用来保证可见性 ...

  4. Java多线程编程——volatile关键字

    (本篇主要内容摘自<Java多线程编程核心技术>) volatile关键字的主要作用是保证线程之间变量的可见性. package com.func; public class RunThr ...

  5. 【java多线程】volatile 关键字

    在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...

  6. Java多线程:volatile 关键字

    一.内存模型的相关概念 大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入.由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存 ...

  7. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  8. (转)Java并发编程:volatile关键字解析

    转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...

  9. Java并发编程:volatile关键字解析(转载)

    转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析   Java并发编程:volatile关键字解析 ...

随机推荐

  1. vs Could Not Connect

    解决,   在win7上卸载IIS 10.0 Express ,安装 IIS7.5 Express

  2. Linux 下phpstudy的安装使用补充说明

    (1)使用方法 在终端中使用sudo 或者 使用管理员账号运行 phpstudy start 开启 (2)命令列表: phpstudy start | stop | restart        开启 ...

  3. recreate dbcontrol on database 11.2.0.1 using emca

    [oracle@osb ~]$ env | grep ORA ORACLE_SID=ACE ORACLE_BASE=/oracle ORACLE_TERM=xterm ORACLE_HOME=/ora ...

  4. Linux:文本处理工具

    闲话少说,列出工具: ========================这些是查看文本用的=========================== 1,cat  用法:cat >f1 直接创建或覆盖 ...

  5. Python2 下Ubuntu linux Mac 安装 PyV8

    在pip install PyV8(注意区分大小写)时,出现了如下报错 command 'x86_64-linux-gnu-gcc' failed with exit status 1 解决方案: 百 ...

  6. 49.ardinality算法之优化内存开销以及HLL算法

    主要知识点 precision_threshold参数的理解 HLL算法优化(hash)         cardinality,count(distinct),5%的错误率,性能在100ms左右   ...

  7. 第一节:初识pandas之Series(上)

    Series线性的数据结构, 也是一个一维数组. 声明:本人Python小白,以下代码只是个人学习的过程,仅仅记录一下学习的点点滴滴,若有错误,还望指正. (注:该代码均在jupyter notebo ...

  8. 【codeforces 510C】Fox And Names

    [题目链接]:http://codeforces.com/contest/510/problem/C [题意] 给你n个字符串; 问你要怎么修改字典序; (即原本是a,b,c..z现在你可以修改每个字 ...

  9. hdu 4707 bellman

    最短路的优先队列做法: #include<stdio.h> #include<queue> #include<string.h> #define N  100010 ...

  10. N天学习一个linux命令之diff

    用途 按行比较文件差异,也可以比较目录 用法 diff [OPTION]... FILES 常用选项 -i --ignore-case 忽略大小写 --ignore-file-name-case 忽略 ...