JAVA并发编程之线程安全性
1、一个对象是否是线程安全的,取决于它是否被多个线程访问。想要使得线程安全,需要通过同步机制来协同对对象可变状态的访问。
2、修复多线程访问可变状态变量出现的错误:1、程序间不共享状态变量 2、状态变量修改为不可变 3、使用同步
3、无状态的对象一定是线程安全的,一个类中如果没有包含任何域及其他类域的引用,则这个类是个无状态的类,类的对象是无状态对象。
4、线程安全下的一些概念:
1、在并发编程中,如果一个包含状态的对象,在执行过程中操作不具备原子性,则会使此变量发生偏差。
2、在并发编程中,如果一个包含状态的对象,在操作过程中存在多个竞态条件,结果会变不可靠。因为后执行的操作,可能会基于前一个操作的状态去执行某个操作,但前一个操作的结果可能会失效,导致后一个操作从全局看是错误的,这叫做先检查后执行错误。
3、复合操作:先检查后执行;读取-修改-写入
4、加锁机制
5、内置锁:同步代码块包括两部分:一个作为锁的对象引用,另一个作为锁保护的代码块。Java内置锁相当于一个互斥锁。
6、重入锁:指如果某个线程已经获取了某个锁,在流程处理过程中,又重新去获取这个锁,则将会成功。
7、用锁来保护状态:由于锁能达到代码路径以串行执行,因此可以通过锁来构造一些协议,实现对共享状态的独占访问,遵循这些协议,则可达到状态一致性目的。避免产生竞态条件:原子操作,比如命中计数器的复合操作或者延迟初始化操作都需要是原子性的。如果在复合操作过程中持有一个锁,则复合操作会变成一个原子操作。但仅仅将复合操作封装到一个同步代码块中是不够的,需要在访问某个变量的所有位置上都使用同步,都使用同一个锁。
对于可能被多个线程同时访问的可变状态变量,在访问时需要同一个锁,这个变量就是被这个锁保护的。
每个对象虽然可以通过一个内置锁受到保护,但这种锁并不能阻止其他线程去访问这个对象,因为某个线程在获得这个对象的锁以后,并不能阻止的是其它线程去获得这个锁,想要对象中的共享状态变量安全,需要自行构造加锁协议或者同步策略,在程序中要自始至终的使用这个策略。
以上的意思是:如果某个对象中的复合操作或者延迟操作想要得到线程安全保护,那么只在这个对象的这些操作上进行内置锁保护是不够的,因为其他线程也会去访问这个对象的共享变量,如果访问的获取操作或者修改操作,那么这个共享变量就变得不安全,怎么达到共享安全呢,需要在这个共享变量的操作上全部使用锁或者不同的策略,这样不管执行什么操作,都是安全的。
还有,如果我们能达到在访问某个共享状态变量时候,都需要持有同一个锁才能访问这个共享状态变量,那么也能达到线程安全,这种安全是建立在这个锁保护的基础上。
JAVA并发编程之线程安全性的更多相关文章
- Java并发编程 (四) 线程安全性
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.线程安全性-原子性-atomic-1 1.线程安全性 定义: 当某个线程访问某个类时,不管运行时环境 ...
- Java并发编程 (五) 线程安全性
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.安全发布对象-发布与逸出 1.发布与逸出定义 发布对象 : 使一个对象能够被当前范围之外的代码所使用 ...
- Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- Java并发编程:线程池的使用(转)
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程控制
在上一篇文章中(Java并发编程:线程的基本状态)我们介绍了线程状态的 5 种基本状态以及线程的声明周期.这篇文章将深入讲解Java如何对线程进行状态控制,比如:如何将一个线程从一个状态转到另一个状态 ...
- Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...
- (转)Java并发编程:线程池的使用
背景:线程池在面试时候经常遇到,反复出现的问题就是理解不深入,不能做到游刃有余.所以这篇博客是要深入总结线程池的使用. ThreadPoolExecutor的继承关系 线程池的原理 1.线程池状态(4 ...
- Java并发编程:线程池的使用(转载)
转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
随机推荐
- 组件向外暴露v-model绑定的参数
<template> <div class="search-box"> <i class="icon-search">< ...
- python opencv:保存图像
- 最全的Java操作Redis的工具类,使用StringRedisTemplate实现,封装了对Redis五种基本类型的各种操作!
转载自:https://github.com/whvcse/RedisUtil 代码 ProtoStuffSerializerUtil.java import java.io.ByteArrayInp ...
- POJ-1087 A Plug for UNIX (网络流)
思路 电器数1 ~ 100,附带100种接口,注意题目:You notice that some of the devices use plugs for which there is no rece ...
- 需要写的CSS博客
重绘与回流 BFC 水平垂直居中 定位 基线各种线 inline-block,img标签空字符
- 吴裕雄--天生自然Numpy库学习笔记:NumPy 矩阵库(Matrix)
import numpy.matlib import numpy as np print (np.matlib.empty((2,2))) # 填充为随机数据 numpy.matlib.zeros() ...
- ES-elasticsearch安装-linux
(1)安装JDK(ES是使用java开发的) (2)安装ES(虚拟机内存大于一个g) 1)创建普通用户启动 2)非常占用内存(默认1个g的内存) (3)创建一个普通用户(用于启动ES) groupad ...
- lc 0228
目录 ✅ 412. Fizz Buzz 描述 解答 c数字转字符: other's c my c tdo py ✅ 235. 二叉搜索树的最近公共祖先 描述 解答 评价者 思路: c py ✅ 412 ...
- comsol日常联系
- Python语言——列表生成式
生成[1x1, 2x2, 3x3, ..., 10x10]列表: >>> L = [] >>> for x in range(1, 11):... >> ...