java程序如何确保多线程的运行安全?
线程的安全问题体现在:
- 原子性:一个或多个操作在CPU执行过程中不被中断的特性
- 可见性:一个线程对共享变量的修改,另一个线程能立刻看到
- 有序性:程序执行的顺序按照代码的先后顺序执行
导致线程存在安全问题的原因:
- 缓存导致可见性问题
- 线程切换导致原子性问题
- 编译优化导致的有序性问题
java给出的解决方法:
- JDK Atomic开头的原子类、synchronized、LOCK,可以解决原子性问题
- synchronized、volatile、LOCK,可以解决可见性问题
- Happens-Before 规则可以解决有序性问题
Happens-Before规则:
因为jvm会对代码进行编译优化,指令会出现重排序的情况,为了避免编译优化对并发编程安全性的影响,需要happens-before规则定义一些禁止编译优化的场景,保证并发编程的正确性。
- 程序顺序性规则:指的是在一个线程内,按照程序代码的顺序,前面的代码运行的结果能被后面的代码可见。
- 传递性规则:传递性,指的是如果A Happens-Before于B,B Happens-Before于C,则A Happens-Before于C。这个是很好理解的。用白话说就是,如果A的操作结果对B可见,B操作结果对C可见,则A的操作结果对C也是可见的。
- volatile变量规则:指对一个volatile变量的写操作,Happens-Before于后续对这个volatile变量的读操作。
- 指的是一个锁的解锁 Happens-Before 于后续对这个锁的加锁。
- 线程start()规则:指的是主线程A启动子线程B后,子线程B能看到主线程在启动线程B前的操作。
- 线程join()规则:指的是线程A调用线程B的interrupt()方法,Happens-Before 于线程B检测中断事件(也就是Thread.interrupted()方法)。这个也很容易理解。
- 线程的interrupt()规则:指的是线程A调用线程B的interrupt()方法,Happens-Before 于线程B检测中断事件(也就是Thread.interrupted()方法)。这个也很容易理解。
- finalize()规则:指的是对象的构造函数执行、结束 Happens-Before 于finalize()方法的开始。
java程序如何确保多线程的运行安全?的更多相关文章
- DOS环境下含包并引用第三方jar的java程序的编译及运行
DOS环境下含包并引用第三方jar的java程序的编译及运行 1.程序目录机构 bin:class文件生成目录 lib:第三方jar包目录 src:源程序文件目录 2.程序代码: 3.程序编译 jav ...
- Java程序在内存中运行详解
目录 Java程序在内存中运行详解 一.JVM的内存分布 二.程序执行的过程 三.只有一个对象时的内存图 四.两个对象使用同一个方法的内存图 五.两个引用指向同一个对象的内存图 六.使用对象类型作为方 ...
- 把java程序作为windows服务运行
参考: https://www.jianshu.com/p/fc9e4ea61e13 https://blog.csdn.net/qq_28566071/article/details/8088250 ...
- JAVA程序—HelloWorld 的编译运行
在我们写好我们的"HelloWorld.java",并且搭建好JAVA的开发环境过后,便可以运行这个JAVA程序了. 具体如何实现,让我们来看看: 打开DOS 通过DOS命令转到& ...
- Java程序在Linux上运行虚拟内存耗用很大
突然集群的2个节点挂了,通过top查看, 虚拟内存22G, 通过 pmap -x 8 | grep anon 一大堆64M Linux下glibc的内存管理机制用了一个很奇妙的东西,叫arena.在g ...
- 初识java——Java程序的历史、开发和运行
上了一节Java试听课,整理出如下笔记. Java最新版本下载 http://www.oracle.com/technetwork/java/javase/downloads/index.ht ...
- [置顶] 如何运行用记事本写的java程序
今天用记事本写了一个java程序,测试能运行,现在把它分解成几个步骤,利于大家理解: 1. 新建一个记事本,后缀名是 .java :然后在里面写一段jav ...
- JAVA设置环境变量和在DOS下运行java程序
在学校实训的这几天,老师带着我们开始深入的复习java.这是第一天的内容哦 对于“JAVA设置环境变量和在DOS下运行java程序”,许多初学者是陌生的,但了解这个却对后期的学习很重要. http:/ ...
- Java程序编译和运行过程之 一个对象的生命之旅(类加载和类加载器)
Java程序从创建到运行要经过两个大步骤 1:源文件(.java)由编译器编译成字节码ByteCode(.class) 2:字节码由Java虚拟机解释并运行 源文件编译成字节码,主要分成两个部分: 1 ...
随机推荐
- 解决overlay2存储驱动的磁盘配额问题
为啥要用overlay2 docker centos(内核3.10)上默认存储驱动是devicemapper 的loop-lvm模式,这种模式是用文件模拟块设备,不推荐生产使用direct lvm又不 ...
- 2020CCPC长春F. Strange Memory
题目大意 一棵以 \(1\) 为根的 \(n(2\leq n\leq 10^5)\) 的树,每个节点 \(i\) 有权值 \(a_{i}(1\leq a_{i}\leq 10^6)\) ,求 \(\s ...
- JZ-035-数组中的逆序对
数组中的逆序对 题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即 ...
- 手写 Vue 系列 之 Vue1.x
前言 前面我们用 12 篇文章详细讲解了 Vue2 的框架源码.接下来我们就开始手写 Vue 系列,写一个自己的 Vue 框架,用最简单的代码实现 Vue 的核心功能,进一步理解 Vue 核心原理. ...
- MM32F0140 UART1空闲中断接收
目录: 1.MM32F0140简介 2.初始化MM32F0140 UART1空闲中断和NVIC中断 3.编写MM32F0140 UART1中断接收和空闲中断函数 4.编写MM32F0140 UART1 ...
- 云原生技术赋能ISV实现应用现代化
日前,由BP商业伙伴主办,中国开源云联盟和云原生应用现代化联盟协办的2021-2022云计算生态峰会成功举办.头部ISV代表.最终用户和云原生技术专家等与会各方围绕"云原生技术赋能ISV&q ...
- CF1385G口胡
只能说很神秘??? 首先观察题面,假设给出的第一个序列为 \(a\),第二个序列为 \(b\).对于 \((a_i,b_i)\) 我们连一条边. 得到的是一个 \(n\) 个点 \(n\) 条边的不一 ...
- 2.3 C++STL vector容器详解
文章目录 2.3.1 引入 2.3.2 代码实例 2.3.3 运行结果 总结 2.3.1 引入 vector 容器 动态数组 可变数组 vector容器 单口容器(尾部操作效率高) vector动态增 ...
- 开启路由器的TCP拦截
TCP拦截即TCP intercept,大多数的路由器平台都引用了该功能,其主要作用就是防止SYN泛洪攻击.SYN攻击利用的是TCP的三次握手机制,攻击端利用伪造的IP地址向被攻击端发出请求,而被攻击 ...
- 『现学现忘』Docker基础 — 29、Docker容器数据卷的应用
目录 1.验证容器和宿主机之间数据共享 2.容器停止退出后,主机修改后数据是否同步 3.带只读权限的挂载数据卷 1.验证容器和宿主机之间数据共享 通过上面的操作,接下来我们演示一下通过数据卷的挂载,实 ...