参考:http://www.cnblogs.com/mengyan/archive/2012/08/22/2651575.html

原子性:所谓原子性就是不可分割的,比如:在我们编程中直接给变量赋值,这就是不可分割的,就具有原子性,相对的,非原子性就是在编程中步骤被分割的,比如编程中的计算,是分步骤进行的,例如:a+=b,其实编程是分为三步,1、先取出a和b的值 2、计算a+b 3、写入内存。这就是非原子性。

可见性:提到可见性,很多同学就会想到一个关键字 volatile ,没错,在多线程中,解决变量的可见性就是利用了volatile这个修饰词。

多线程变量不可见:当一个线程对一变量a修改后,还没有来得及将修改后的a值回写到主存,而被线程调度器中断操作(或收回时间片),然后让另一线程进行对a变量的访问修改,这时候,后来的线程并不知道a值已经修改过,它使用的仍旧是修改之前的a值,这样修改后的a值就被另一线程覆盖掉了。

多线程变量可见:被volatile修饰的成员变量在每次被线程访问时,都强迫从内存中重读该成员变量的值;而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存,这样在任何时刻两个不同线程总是看到某一成员变量的同一个值,这就是保证了可见性。

举个例子:

编写一个线程类:

public class MyThread4 implements Runnable {
private boolean isRun = true; public boolean isRun() {
return isRun;
} public void setRun(boolean run) {
isRun = run;
} @Override
public void run() {
System.out.println("4开始运行了");
while (isRun){ }
}
}

main()方法运行

MyThread4 myThread4 = new MyThread4();
Thread thread = new Thread(myThread4);
thread.start();
try {
Thread.sleep(100);
myThread4.setRun(false);
System.out.println("停了吗");
} catch (InterruptedException e) {
e.printStackTrace();
}

看运行结果,会发现线程进入了死循环,myThread4.setRun(false);这行代码并没有使线程重新拿到 isRun 的赋值,这说明线程之间对同一个变量的操作是不可见的。

当我们把 isRun 加上volatile关键字时如下:

public class MyThread4 implements Runnable {
private volatile boolean isRun = true; public boolean isRun() {
return isRun;
} public void setRun(boolean run) {
isRun = run;
} @Override
public void run() {
System.out.println("4开始运行了");
while (isRun){ }
}
}

再次运行我们会发现,代码不会进入死循环,由此可见,关键字volatile 保障了线程之间变量的可见性。

拓展:当我们在while循环中加入有synchronized关键字修饰的方法时,比如System.out.println();这时代码也不会陷入死循环,因此synchronized除了保障了原子性外,其实也保障了可见性。因为synchronized无论是同步的方法还是同步的代码块,都会先把主内存的数据拷贝到工作内存中,同步代码块结束,会把工作内存中的数据更新到主内存中,这样主内存中的数据一定是最新的。

java多线程补:充原子性和可见性的更多相关文章

  1. java多线程3:原子性,可见性,有序性

    概念 在了解线程安全问题之前,必须先知道为什么需要并发,并发给我们带来什么问题. 为什么需要并发,多线程? 时代的召唤,为了更充分的利用多核CPU的计算能力,多个线程程序可通过提高处理器的资源利用率来 ...

  2. java并发特性:原子性、可见性、有序性

    要想并发程序正确地执行,必须要保证原子性.可见性以及有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后 ...

  3. 「跬步千里」详解 Java 内存模型与原子性、可见性、有序性

    文题 "跬步千里" 主要是为了凸显这篇文章的基础性与重要性(狗头),并发编程这块的知识也确实主要围绕着 JMM 和三大性质来展开. 全文脉络如下: 1)为什么要学习并发编程? 2) ...

  4. java内存模型的原子性、可见性、有序性与指令重排序

    在并发编程中,我们通常会遇到以下三个概念:原子性.可见性和有序性.我们先看具体看一下这三个概念: 1.原子性 操作时不可分割的比如a=0,此操作不可分割,而++a,实际上是a=a+1,为两个操作.想将 ...

  5. JAVA多线程提高五:原子性操作类的应用

    当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可能i不等于3,而是等于2.因为A和B线程在更新变量i ...

  6. JAVA多线程学习九-原子性操作类的应用

    当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可能i不等于3,而是等于2.因为A和B线程在更新变量i ...

  7. Java多线程基础总结

    一.线程和进程关系 二.创建方式1.继承Thread类,重写run方法2.实现Runable接口,重写run方法3.使用匿名内部类 三.API接口start()currentThread() 获取当前 ...

  8. java多线程(4)---volatile关键字

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

  9. java多线程03-----------------volatile内存语义

    java多线程02-----------------volatile内存语义 volatile关键字是java虚拟机提供的最轻量级额的同步机制.由于volatile关键字与java内存模型相关,因此, ...

随机推荐

  1. Squid 缓存代理服务器的完整配置

    Squid 缓存代理服务器 Squid 的作用 1.通过缓存的方式为用户提供web访问加速 2.对用户的web访问进行过滤控制 缓存代理服务器又分为普通代理服务器,透明代理服务器,和反向代理服务器. ...

  2. Spring 框架的 applicationContext.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  3. MySQL前后台交互登录系统设计

    1.首先我们做一个前台的注册页面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...

  4. 初识python(二)

    初识python(二) 1.变量 变量:把程序运行的中间结果临时的存在内存里,以便后续的代码调用. 1.1 声明变量: #!/usr/bin/env python # -*- coding: utf- ...

  5. EasySQLMAIL使用实践系列

    原文:http://blog.sina.com.cn/s/articlelist_5713986487_0_1.html 通过sql语句发送微信消息(转) 使用EasySQLMAIL的外部接口功能实现 ...

  6. 用仿ActionScript的语法来编写html5——第二篇,利用Sprite来实现动画

    上一篇,我已经模仿as,加入了LBitmap和LBitmapData类,并且用它们实现了静态图片的显示.这次用Sprite来动态显示图片.依然遵循上一篇对显示对象的处理的思路,添加LSprite类,并 ...

  7. Apache添加多端口

    Apache\conf 目录下 添加端口监听     Vhost.conf简单写写

  8. LeetCode:全排列II【47】

    LeetCode:全排列II[47] 参考自天码营题解:https://www.tianmaying.com/tutorial/LC47 题目描述 给定一个可包含重复数字的序列,返回所有不重复的全排列 ...

  9. 102. Binary Tree Level Order Traversal ------层序遍历

      Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to righ ...

  10. Calendar的那些神坑

    参考我的博客:http://www.isedwardtang.com/2017/08/31/java-calendar-bug/