synchronized,volatile都解决了共享变量 value 的内存可见性问题,但是前者是独占锁,同时只能有一个线程调用 get()方法,其他调用线程会被阻塞, 同时会存在线程上下文切换和线程重新调度的开销,这也是使用锁方式不好的地方。 而后者是非阻塞算法,不会造成线程上下文切换的开销。

volatile 虽然提供了可见性保证,但并不保证操作的原子性。

一般在什么时候才使用 volatile 关键字呢?

  • 写入变量值不依赖、变量的当前值时。 因为如果依赖当前值,将是获取一计算一写入 三步操作,这三步操作不是原子性的,而 volatile 不保证原子性。
  • 读写变量值时没有加锁。 因为加锁本身已经保证了内存可见性,这时候不需要把变量声明为 volatile 的。
/**
* volatile不能代替锁
* volatile无法保证i++的原子性操作
*/
public class VolatileDemo {
static volatile int i = 0;
public static class PlusTask implements Runnable {
@Override
public void run() {
// synchronized (VolatileDemo.class){
for (int j = 0; j < 10000; j++) {
i++;
}
// }
}
} public static void main(String[] args) throws InterruptedException{
Thread[] threads = new Thread[10];
for (int a = 0; a < 10; a++) {
threads[a] = new Thread(new PlusTask());
threads[a].start();
}
for (int a = 0; a < 10; a++) {
threads[a].join();
}
System.out.println(i);//i的值小于10000
}
}
//可见性
public class NoVisibility {
private static volatile boolean ready;
private static int number;
public static class ReadThread extends Thread{
@Override
public void run() {
while (!ready); //没使用volatile声明ready前,主线程修改ready的状态,ReadThread无法"看到"主线程中的修改
System.out.println(number);
}
}
public static void main(String[] args) throws InterruptedException{
ReadThread readThread = new ReadThread();
readThread.start();
Thread.sleep(1000);
number = 42;
ready = true;
Thread.sleep(1000);
}
}

13.volatile与synchronized比较的更多相关文章

  1. JAVA Synchronized (三) volatile 与 synchronized 的比较

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

  2. Thread 学习记录 <1> -- volatile和synchronized

    恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1;  ...

  3. volatile与synchronized的区别

    1.锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility). 互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一 ...

  4. 从JAVA看C#中volatile和synchronized关键字的作用

    最近一直在想C#中 volatile关键字到底是用来干什么的?查了很多.NET的文章都是说用volatile修饰的变量可以让多线程同时修改,这是什么鬼... 然后查到了下面这篇JAVA中关于volat ...

  5. 关于volatile和synchronized

    这个可能是最好的对比volatile和synchronized作用的文章了.volatile是一个变量修饰符,而synchronized是一个方法或块的修饰符.所以我们使用这两种关键字来指定三种简单的 ...

  6. Volatile和Synchronized对可见性和原子性的支持

    在学习并发编程的时候,遇见了volatile和synchronized关键字问题,volatile是可以保证可见性,但无法保证原子性,synchronized关键字由于其是加锁机制,肯定是可以保证原子 ...

  7. volatile 与 synchronized 区别

    在Java中,为了保证多线程读写数据时保证数据的一致性,可以采用两种方式: 同步 如用synchronized关键字,或者使用锁对象. volatile 使用volatile关键字用一句话概括vola ...

  8. 剑指Offer——线程同步volatile与synchronized详解

    (转)Java面试--线程同步volatile与synchronized详解 0. 前言 面试时很可能遇到这样一个问题:使用volatile修饰int型变量i,多个线程同时进行i++操作,这样可以实现 ...

  9. 并发编程之ThreadLocal、Volatile、synchronized、Atomic关键字扫盲

    前言 对于ThreadLocal.Volatile.synchronized.Atomic这四个关键字,我想一提及到大家肯定都想到的是解决在多线程并发环境下资源的共享问题,但是要细说每一个的特点.区别 ...

随机推荐

  1. linux下清空文件内容

    在命令行下#cat /dev/null >listener.log

  2. 运行rabbitmq

    docker run -d -p 5672:5672 -p 15672:15672 --name myrabbitmq c4663bdca2cd

  3. Linux系统重要文件(三)

    一系统运行级别文件 文件路径:/etc/inittab 文件作用说明:定义系统启动后,自动开启哪些软件程序系统 runlevel 查看当前运行级别 centos6系统运行级别: 7个级别      0 ...

  4. 【Linux】端口反查进程

    平时时常遇到端口占用的情况,又不知道端口是哪个服务启的. 本文以80端口为例. [root@localhost jenkins]# netstat -tunlp | grep 80 tcp6 0 0 ...

  5. python3安装pdfminer并使用

    1.python3不同与2版本不能使用pdfminer pip install pdfminer3k 2.使用pdfminer解析相应文档并保存到相应的文件夹中 # encoding : udf-8 ...

  6. 简单数学算法demo和窗口跳转,关闭,弹框

     简单数学算法demo和窗口跳转,关闭,弹框demo <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&quo ...

  7. python global和nonlocal的使用

    ◆global和nonlocal是Python的两个重要变量作用域关键字 1.global用在全局变量,应用场景: 变量定义在函数外部的时候,如果函数里面想改变这个全局变量的值,需要在当前的引用函数里 ...

  8. SelfCert wcf中 生成x5.09证书的工具

    http://blog.pluralsight.com/selfcert-create-a-self-signed-certificate-interactively-gui-or-programma ...

  9. 汇编指令ADD

    格式: ADD OPRD1,OPRD2 功能: 两数相加(不带进位) 例子: add ax,bx add ax,ax 解释:

  10. jmeter_使用命令行运行

    使用非GUI模式,即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资源. Windows下以命令行模式运行的方法: 1.命令介绍 jmeter -n -t <testfile f ...