synchronized和volatile关键字
synchronized
同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰方法或者代码块。
volatile
用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的值。volatile很容易被误用,用来进行原子性操作。
以下两段程序演示了两者区别
package net.dp.volatileTest;
public class JoinThread extends Thread {
public static volatile int n = 0;
public void run() {
for (int i = 0; i < 10; i++)
try {
n = n + 1;
sleep(3); // 为了使运行结果更随机,延迟3毫秒
} catch (Exception e) {
}
}
public static void main(String[] args) throws Exception {
Thread threads[] = new Thread[100];
for (int i = 0; i < threads.length; i++)
// 建立100个线程
threads[i] = new JoinThread();
for (int i = 0; i < threads.length; i++)
// 运行刚才建立的100个线程
threads[i].start();
for (int i = 0; i < threads.length; i++)
// 100个线程都执行完后继续
threads[i].join();
System.out.println(" n= " + JoinThread.n);
//执行结果 n < 1000
}
}
程序的运行结果是n小于1000.
原因:Java在创建线程的时候会为每一个线程分配线程当前的内存空间用来存放当前线程中的变量,存储在栈中;这些变量最终的值是存储在堆中。也就是说栈中会有堆中变量值的副本。volatile关键字是保证不同线程对该变量的访问是从堆中获取,拿到的是同一个变量的真实值不是栈中的副本。但是这并不能保证该操作是原子性的。在程序中n = n + 1操作就不是原子性的所以才会出错。
使用synchronized关键字解决该问题。
package net.dp.volatileTest;
public class JoinThread2 extends Thread {
public static int n = 0;
public static synchronized void inc() {
n++;
}
public void run() {
for (int i = 0; i < 10; i++)
try {
inc(); // n = n + 1 改成了 inc();
sleep(3); // 为了使运行结果更随机,延迟3毫秒
} catch (Exception e) {
}
}
public static void main(String[] args) throws Exception {
Thread threads[] = new Thread[100];
for (int i = 0; i < threads.length; i++)
// 建立100个线程
threads[i] = new JoinThread2();
for (int i = 0; i < threads.length; i++)
// 运行刚才建立的100个线程
threads[i].start();
for (int i = 0; i < threads.length; i++)
// 100个线程都执行完后继续
threads[i].join();
System.out.println(" n= " + JoinThread2.n);
}
}
程序执行结果是1000
使用synchronized关键字对自增操作修饰,保证了自增的原子操作。
synchronized和volatile关键字的更多相关文章
- 10-Java中共享内存可见性以及synchronized和volatile关键字
Java中共享变量的内存可见性 我们首先来看一下在多线程下处理共享变量时Java的内存模型,如图所示 Java内存模型规定,将所有的变量都存放在主存中,当线程使用变量的时候,会把主内存里面的变量赋值到 ...
- Java并发编程学习笔记 深入理解volatile关键字的作用
引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的 ...
- volatile关键字的作用
引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的 ...
- volatile关键字的介绍和使用
关键字volatile的主要作用是使变量在过个线程中可见 1.假设volatile不存在我们将会面对的问题 public class PrintString implements Runnable { ...
- java面试记录二:spring加载流程、springmvc请求流程、spring事务失效、synchronized和volatile、JMM和JVM模型、二分查找的实现、垃圾收集器、控制台顺序打印ABC的三种线程实现
注:部分答案引用网络文章 简答题 1.Spring项目启动后的加载流程 (1)使用spring框架的web项目,在tomcat下,是根据web.xml来启动的.web.xml中负责配置启动spring ...
- [面试必备]深入理解Java的volatile关键字
前言 在Java并发编程中,volatile关键字有着至关重要的作用,在面试中也常常会是必备的一个问题.本文将会介绍volatile关键字的作用以及其实现原理. volatile作用 volatile ...
- Java多线程6:synchronized锁定类方法、volatile关键字及其他
同步静态方法 synchronized还可以应用在静态方法上,如果这么写,则代表的是对当前.java文件对应的Class类加锁.看一下例子,注意一下printC()并不是一个静态方法: public ...
- volatile关键字和synchronized关键字
volatile关键字: 可以用来修饰字段(成员变量),就是告知程序任何对该变量的访问均需要从共享内存中获取,而对它的改变必须同步刷新回共享内存,它能保证所有线程对变量访问的可见性. synchron ...
- 并发编程之ThreadLocal、Volatile、synchronized、Atomic关键字扫盲
前言 对于ThreadLocal.Volatile.synchronized.Atomic这四个关键字,我想一提及到大家肯定都想到的是解决在多线程并发环境下资源的共享问题,但是要细说每一个的特点.区别 ...
随机推荐
- C语言传递二维数组
方法一, 形参给出第二维的长度. 例如: #include <stdio.h> ] ) { int i; ; i < n; i++) printf("/nstr[%d] = ...
- 吴裕雄 python 机器学习——模型选择分类问题性能度量
import numpy as np import matplotlib.pyplot as plt from sklearn.svm import SVC from sklearn.datasets ...
- 【PAT甲级】1080 Graduate Admission (30 分)
题意: 输入三个正整数N,M,K(N<=40000,M<=100,K<=5)分别表示学生人数,可供报考学校总数,学生可填志愿总数.接着输入一行M个正整数表示从0到M-1每所学校招生人 ...
- 例题3_2 WERTYU(UVa10082)
把手放在键盘上时,稍不注意就会往右错一位.这样,输入Q会变成W,输入J会变成K等.键盘如下图所示: 输入一个错位后敲出的字符串(所有字母均大写),输出打字员本来想打出的句子.输入保证合法,即一定是错位 ...
- laravel 模拟数据批量添加
模拟User表结构: database/factories/UserFactory.php(模型工厂) <?php use App\Models\User; use Illuminate\Sup ...
- Bugku-CTF社工篇之社工进阶
- Kubernetes的service资源介绍
service 三种工作模式:userspace.iptables.ipvs 删除手动创建的service [root@master ~]# kubectl delete svc redis serv ...
- 吴裕雄--天生自然TensorFlow2教程:手写数字问题实战
import tensorflow as tf from tensorflow import keras from keras import Sequential,datasets, layers, ...
- eclipse修改工作空间编码格式
一.修改workspace默认编码 eclipse打开window -> 打开preferences 二.修改jsp默认编码 eclipse打开window -> 打开preference ...
- XCOJ1250: 语言战争
1250: 语言战争 时间限制: 1 Sec 内存限制: 64 MB提交: 203 解决: 46 标签提交统计讨论版 题目描述 llc和yrc语言的优劣一直都是大家所争论的焦点,但它们之间最大的区 ...