可见性:

JAVA内存模型:

  

java为了加快程序的运行效率,对一些变量的操作是在寄存器或者CPU缓存上进行的,后面再同步到主存中

看上图,线程在运行的过程中,会从主内存里面去去变量,读到自己的空间内,最后再刷新进去,而volatile的出现,使得可以直接去主存中数据,换句话来说,一般情况下更新了数据之后需要等待一段时间刷新主内存来保证数据的统一,volatile让其他线程更快的知道这个改变,因此他修饰的变量具有可见性

指令重排序

  volatile禁止指令重排序

  指令重排序:为了提高运行效率对代码进行优化,不保证语句执行顺序和代码中一样,但是保证结果一样。

非原子性

  原子性:一系列操作要么全部执行,要么都不执行

  常见的 i++操作:先取出i的值,+1后,写回,这不是原子操作,进行了三步

 public class MyThread extends Thread {
public volatile static int count; private static void addCount() {
for (int i = 0; i < 100; i++) {
count++;
}
System.out.println("count=" + count);
} @Override
public void run() {
addCount();
}
} public class Run {
public static void main(String[] args) {
MyThread[] mythreadArray = new MyThread[100];
for (int i = 0; i < 100; i++) {
mythreadArray[i] = new MyThread();
} for (int i = 0; i < 100; i++) {
mythreadArray[i].start();
}
}
}

因此这个的结果并不会是10000,因为可能在i++分步操作的时候,会有其他的线程进来取值,而我还没来得及改变地址区域里面的值

比较

  1、volatile是轻量级的,只能修饰变量,synchronized是重量级的,还可以修饰方法

  2、volatile只能保证数据的可见性,不会阻塞,synchronized既能保证可见性也能保证原子性,会出现争抢锁的情况,会出现阻塞

  3、volatile不能保证线程安全,synchronized可以保证线程安全

Java多线程之volatile与synchronized比较的更多相关文章

  1. JAVA多线程之volatile 与 synchronized 的比较

    一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...

  2. Java多线程之volatile详解

    本文目录 从多线程交替打印A和B开始 Java 内存模型中的可见性.原子性和有序性 Volatile原理 volatile的特性 volatile happens-before规则 volatile ...

  3. JAVA 多线程之volatile的介绍

    volatile的介绍 volatile的主要作用是:提示编译器该对象的值有可能在编译器未监测的情况下被改变. volatile类似于大家所熟知的const也是一个类型修饰符.volatile是给编译 ...

  4. java多线程之volatile关键字

    public class ThreadVolatile extends Thread { public boolean flag=true; @Override public void run() { ...

  5. Java多线程之volatile关键字《一》

    关键字volatile的主要作用是使变量在多个线程间可见. 1.关键字volatile与死循环 如果不是在多继承的情况下,使用继承Thread类和实现Runnable接口在取得程序运行的结果上并没有什 ...

  6. Java多线程之ConcurrentSkipListMap深入分析(转)

    Java多线程之ConcurrentSkipListMap深入分析   一.前言 concurrentHashMap与ConcurrentSkipListMap性能测试 在4线程1.6万数据的条件下, ...

  7. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  8. java多线程之yield,join,wait,sleep的区别

    Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...

  9. Java多线程之Runnable与Thread

    Java多线程之Thread与Runnable 一.Thread VS Runnable 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类和 ...

随机推荐

  1. linq 和lamba表达式

    一.什么是Linq(what)二.Linq的优点(why)三.Linq查询的步骤(how)四.查询基本操作五.結合實例代碼(具體聯繫用linqtosql來寫的增刪改查)一.什么是Linq(what). ...

  2. python-装饰器的简单使用

    一.介绍 首先我们先来看一个简单的例子,在基础平台中有一个home()和tv()函数,在业务平台中调用此函数时,给出了响应的打印内容: 基础平台: def home(): print('welcome ...

  3. 以EF形式操作mysql数据库

    1.引入Nuget包: 2.书写EF操作上下文 public class MySqlContext:DbContext { protected override void OnConfiguring( ...

  4. byte转换字符串(string)+字符串转换byte

    C# 中字符串string和字节数组byte[]的转换 //string转byte[]: byte[] byteArray = System.Text.Encoding.Default.GetByte ...

  5. java使用Redis(六个类型)

    下载插件:https://mvnrepository.com/artifact/redis.clients/jedis/3.0.0 maven项目依赖: <dependency> < ...

  6. Classless Interdomain Routing (CIDR)

    IP Address Problems IP Address Exhaustion Class A, B, and C address structure inefficient Class B to ...

  7. Java JVM技术

    .1.     java监控工具使用 .1.1.    jconsole jconsole是一种集成了上面所有命令功能的可视化工具,可以分析jvm的内存使用情况和线程等信息. 启动jconsole 通 ...

  8. Ubuntu下配置安装telnet server

    1.安装xinetd 以及telnetd # apt-get install xinetd telnetd 2.配置文件/etc/inetd.conf #vi /etc/inetd.conf # St ...

  9. File常见操作函数

    String Name = File.getName();  //获得文件或文件夹的名称: String parentPath = File.getParent();  //获得文件或文件夹的父目录 ...

  10. Flask—10-项目部署(02)

    项目部署 WEB工作原理 客户端(chrom) <=> WEB服务器(nginx) <=> WSGI(uWSGI) <=> Python(Flask) <=& ...