构建了100个线程, Volatile变量具有 synchronized 的可见性特性,但是不具备原子特性。
同时访问操作i,如果i在使用i++时候是对自身变量的操作,实际它这样的操作不是原子操作。下边我们用一段代码试试。
/**
* Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。这两种机制的提出都是为了实现代码线程的安全性。 其中 Volatile
* 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错。
*
* @author Janle
*
*/
public class volatile关键字 {
public static void main(String[] args) {
Thread threads[] = new Thread[100];
for (int i = 0; i < threads.length; i++)
// 建立100个线程
threads[i] = new ThreadVolatile();
for (int i = 0; i < threads.length; i++)
// 运行刚才建立的100个线程
threads[i].start();
for (int i = 0; i < threads.length; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 如果对n的操作是原子级别的,最后输出的结果应该为n=1000,很多时侯输出的n都小于1000.这说明n=n+1不是原子级别的操作。
* 原因是声明为volatile的简单变量如果当前值由该变量以前的值相关,那么volatile关键字不起作用,
* 也就是说如下的表达式都不是原子操作:
* n = n + 1;
* n++;
*/
System.out.println("n=" + ThreadVolatile.n);
}
}
class ThreadVolatile extends Thread {
public static volatile int n = 0;
public static synchronized void inc() {
n++;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
/**
* 这里注意:
* 当变量的值由自身的上一个决定时,如n=n+1、n++等,volatile关键字将失效,只有当变量的值和自身上一个值无关时对该变量的操作才是原子级别的,
* 如n = m + 1,这个就是原级别的。所以在使用volatile关键时一定要谨慎,如果自己没有把握,可以使用synchronized来代替volatile。
*/
//n = n + 1;
inc();//// n = n + 1 改成了 inc();使用这个才能保证是原来的操作,并不是只要简单类型变量使用volatile修饰,对这个变量的所有操作都是原来操作
sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
总结:
用写操作时候不能依赖于当前值【当前获得的值不能被修改】。
该变量没有包含在具有其他变量的计算公式中。
volatile修饰设计用来修饰被不同线程访问和修改的变量。如果不加入volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。
分享到:
相关推荐
Java 线程 volatile 关键字详解 Java™ 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。volatile 变量的同步性较差,但它有时更简单并且开销更低。volatile 变量可以被看作是一种 “程度较轻的 ...
Java多线程volatile关键字详解 Java多线程volatile关键字详解主要介绍了Java多线程volatile关键字的应用和原理。volatile是一种轻量同步机制,可以确保变量的可见性和顺序性,但不保证原子性。 volatile关键字的...
在多线程环境中,如果一个操作不能被中断,那么它就是原子性的。例如,对于一个整型变量的自增操作,在没有额外的同步措施的情况下,并不是原子性的,因为它涉及到读取旧值、计算新值和写入新值三个步骤,任何中间...
以前我们说过在一些简单的例子中,比如为一个字段赋值或递增该字段,我们需要对线程进行同步,虽然lock可以满足我们的需要,但是一个竞争锁一定会导致阻塞,然后忍受线程上下文切换和调度的开销,在一些高并发和性能...
`volatile`关键字是C++和Java等编程语言中用于处理多线程环境或者与硬件交互时的一个关键特性。它主要用于修饰变量,表明该变量的值可能会在编译器不知情的情况下发生变化,例如由其他线程修改、外部硬件事件影响...
在实际应用中,volatile关键字可以用于多种场景,例如,在操作系统中,volatile关键字可以用于提供对特殊地址的稳定访问,防止编译器对访问该变量的代码进行优化。在硬件编程中,volatile关键字可以用于提供对硬件...
在IT行业中,volatile关键字在编程,尤其是嵌入式系统和多线程编程中扮演着重要的角色。本篇文章将深入探讨volatile关键字的作用,并结合GD32F303单片机的使用场景,来阐述它在实际开发中的应用。 首先,volatile...
Java中的Volatile关键字详解是Java中的一种关键字,用于保证线程之间的可见性、原子性和有序性。下面是对Java中的Volatile关键字详解的知识点总结: 一、基本概念 1. 可见性:可见性是一种复杂的属性,因为可见性...
volatile关键字是Java语言中的一种机制,用于保证变量在多线程之间的可见性。它是Java.util.concurrent包的核心,没有volatile就没有那么多的并发类供我们使用。本文详细解读一下volatile关键字如何保证变量在多线程...
总结来说,volatile关键字在Java多线程编程中起着关键作用,它提供了轻量级的同步机制,通过内存屏障保证了变量的可见性和有序性,避免了多线程环境下数据不一致的问题。但需要注意的是,volatile不能保证操作的原子...
线程安全、volatile关键字、原子性、并发包、死锁、线程池学习笔记
volatile 关键字在 C 语言中的使用方法 在 C 语言中,volatile 关键字是用来指定变量的存储类别的,它告诉编译器这个变量的值可能会在编译器不知道的情况下被修改,因此需要重新加载这个变量的值。volatile 关键字...
Java并发编程中,volatile关键字扮演着重要的角色,它是一种轻量级的同步机制,与synchronized相比,volatile在性能上更优,因为它不会导致线程阻塞。在深入理解volatile的关键特性之前,我们需要先了解Java内存模型...
在Java多线程编程中,volatile关键字扮演着重要的角色,它确保了被声明为volatile的变量在多个线程之间的可见性。然而,尽管volatile能够提供一定程度的线程安全,但并不能保证所有操作都是原子性的。这正是为什么在...
`volatile`关键字在Java多线程编程中起到了重要的作用,它提供了轻量级的同步机制,保证了共享变量的可见性。然而,它并不提供原子性保证,因此在处理复合操作时需谨慎使用。在设计并发程序时,理解`volatile`的工作...
在Java编程中,volatile关键字是一个至关重要的概念,尤其在多线程环境下,理解并正确使用volatile是面试时必不可少的知识点。volatile被视为synchronized的一种轻量级实现,但两者在特性上存在显著差异。 首先,...
2. 使用volatile关键字在多线程环境下:volatile关键字可以用于多线程环境下,保证线程之间操作的可见性和有序性。 四、示例代码 以下是一个示例代码,演示了volatile关键字的使用: ```java public class ...
内存栅栏和volatile关键字在多线程编程中扮演着至关重要的角色,它们是确保线程安全和正确数据同步的关键机制。本文将深入探讨这两个概念,以及它们如何在.NET环境中工作。 首先,我们要理解的是,现代计算机为了...