java并发编程实战-第三章-对象的共享

3.1可见性

  • 首先我们需要知道的是,java的线程都有自己独立的缓存,线程之间进行共享变量的交互是通过自身和缓存和主存的交互实现的。
  • 如果线程的每次更改缓存都刷入主存,主存每次被一个线程的缓存修改,都通知所有的线程刷新自身的缓存的话,那样就太不经济了。
  • 由于1和2,就会产生一个现象:当线程1修改了一个共享变量之后,线程2获取的共享变量还是更改前的值。即线程1更改共享变量并没有刷入主存,或者线程2并没有去主存中获取到新的共享变量,或以上两者皆有
  • 为了解决内存可见性我们可以使用volatile关键字和同步这两种方式
  • 变量的读取,指令重排序

失效数据

非原子的64位操作

当读取一个非volatile类型的long变量时,如果对该变量的读操作和写操作在不同的线程中执行,那么很可能读取到某个值的高32位和另外一个值的低32位

加锁和可见性

加锁的含义不仅互斥,还包括内存可见性

volatile变量

  • 用来确保变量的更新操作通知到其他线程
  • 编译器与运行时都会注意到这个变量时共享的,不会进行重排序
  • volatile不会被缓存在寄存器或者其他处理器不可见的地方,读取变量时,总能返回最新的写入值

满足所有条件,才应该使用volatile

  • 对变量的写入不依赖变量的当前值,只有单个线程更新变脸的值
  • 该变量不会与其他状态一起纳入不变形条件中
  • 在访问时不需要加锁

3.2发布与溢出

一般自定义类需要考虑发布(构造方法), juc的类已经处理过了

发布:是对象能够在当前作用域之外的代码中使用

  • 将对象的引用存储到公共静态域。
  • 在非私有方法中返回引用。
  • 在发布某对象的时候可能会间接发布本不想发布的对象,如一个private的数组,一旦被发布,其中储存的对象也会被发布

溢出:不应该发布的被发布了

类对自己的内部状态进行了同步操作,如果发布出去可能会破坏封装性,并使程序难以维护不变性条件 一个对象在尚未准备好就将它发布出去——溢出。

  • “内部类发布也会引发溢出”,因为只有当对象通过构造函数返回之后,才处于稳定状态。这种发布会导致this溢出。
  • “即使在构造函数的最后一行发布也会有该问题”,指令重排序可能会引发一些奇怪的问题。而且该引用已经不是null了,但是内容还没有初始化完毕也有可能。
  • “不要让this在构造期溢出!”

常见错误

  • 1.在构造函数中创建并启动线程 这个时候线程已经获得了this的引用(即使是隐式的,因为该Runnable或者Thread是所属对象的内部类),this引用几乎总是被新线程所共享。 所以在构造函数中创建线程没有错误,但是不要在构造函数中启动它。
  • 2.注册一个内部类,使用this方法 可以使用静态工厂和私有构造函数来解决这个问题。

3.3线程封闭

数据仅在单线程中被访问,即数据不共享。 几种方式:

特定的方法

例如在一个线程中进行 读取修改写入,其他线程中进行读取

栈封闭

引用在局部变量中 注意不要让当前线程中的对象从所在线程溢出!

java的ThreadLocal

使用ThreadLocal可以做到线程隔离,每个线程都有自己单独的一个区域保存变量。

3.4不变性对象

  • 不可变对象满足下列条件:
    1. 所有域是final的,域内部的域也是final的
    2. 所有域不可改变
    3. this没有在构造的时候逸出

final域

使用volatile类型来发布不可变对象

3.5安全发布

不正确的发布:正确的对象被破坏

导致其他县城看到尚未创建完的对象

不可变对象与初始化安全

安全发布的常用模式

  1. 在静态初始化对象引用,因为JVM的类加载过程中是同步的
  2. 对对象引用使用volatile或AtomicReference
  3. 将对象引用放入final域中
  4. 对对象引用加锁

案例:

  • 将一个键值对放入HashTable,syhronizedMap或者ConcurrentMap中
  • 静态构造的对象 public static Holder holder= new Holder(42)

事实不可变对象

程序不会去修改,例如Date虽然是可变的,但是放入了同步的HashMap中,且不会修改,那么就认为是不可变的对象

可变对象

  • 不仅要保证发布时的状态可见性
  • 每次访问时同样需要使用同步来确保后需修改操作的可见性

小结

  • 不可变对象可以通过任意机制来发布()
  • 事实不可变对象必须通过安全方式来发布
  • 可变对象必须通过安全方式来发布,并且是线程安全的或者由某个所保护起来

安全的共享对象

在发布一个对象的时候需要明确指出该对象的多线程共享规则:

  1. 是线程封闭?:只能由一个线程拥有
  2. 是只读共享?:只能并发读
  3. 是线程安全共享?:类内部实现了同步,可以随意使用
  4. 是保护对象?:类内部没有实现同步,需要使用者在外部同步 原文地址: www.victor123.cn/2018/04/15/…

转载于:https://juejin.im/post/5ad2a0a45188257ddb100f27

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GitHub(从安装到使用)

一、安装Git for Windows(又名msysgit) 下载地址: https://git-for-windows.github.io/ 在官方下载完后,安装到Windows Explorer integration的时候,将选项中将“Git Bash here”和“Git GUI here”打对勾。 然后就一直next直到Fi…

Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别、不可重复读与幻读的区别

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 spring事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过&#x…

Google编程之夏入围项目公布

Google编程之夏(Google Summer of Code),是由Google公司所主办的年度程式设计比赛,第一届从2005年开始。“Summer of Code”之名取自1967年的“夏日之爱”(Summer of Love)风潮。比赛的主要目的是鼓励学生参…

普通索引 唯一索引 主键索引 候选索引

普通索引 最基本的索引类型&#xff0c;没有唯一性之类的限制。普通索引可以通过以下几种方式创建&#xff1a; 创建索引&#xff0c;例如CREATE INDEX <索引的名字> ON tablename (列的列表)&#xff1b; 修改表&#xff0c;例如ALTER TABLE tablename ADD INDEX [索引…

Android 基于注解IOC组件化/模块化的架构实践

当前参与的项目历史也很久远&#xff0c;第一行代码据说是写于2014年的某一天&#xff0c;那时Android用的ide还是Eclipse、那时Android还没有很好的架构指导&#xff08;mvp、mvvm&#xff09;、那时Android最新的版本是5.0、那时Android的Material Design还没流行……背景随着…

网络爬虫--14.【糗事百科实战】

文章目录一. 要求二. 参考代码一. 要求 爬取糗事百科段子&#xff0c;假设页面的URL是 http://www.qiushibaike.com/8hr/page/1 使用requests获取页面信息&#xff0c;用XPath / re 做数据提取 获取每个帖子里的用户头像链接、用户姓名、段子内容、点赞次数和评论次数 保存到…

bzoj 5369: [Pkusc2018]最大前缀和

Description 小C是一个算法竞赛爱好者&#xff0c;有一天小C遇到了一个非常难的问题&#xff1a;求一个序列的最大子段和。 但是小C并不会做这个题&#xff0c;于是小C决定把序列随机打乱&#xff0c;然后取序列的最大前缀和作为答案。 小C是一个非常有自知之明的人&#xff0c…

微软:软件帝王的复兴之路

可以说在过去的两个月IT界所发生的一切都非同寻常&#xff0c;乔布斯辞职了&#xff0c;Google把Motorola并购了&#xff0c;微软炫了一下Windows 8&#xff0c;还宣布开始用ARM了&#xff0c;Google开始和英特尔合作了&#xff0c;AT&T与T-Mobile的并购也在紧密锣鼓进行中…

jdbc和odbc区别

ODBC(Open Database Connectivity&#xff0c;开放数据库互连)是微软公司开放服务结构(WOSA&#xff0c;Windows Open Services Architecture)中有关数据库的一个组成部分&#xff0c;它建立了一组规范&#xff0c;并提供了一组对数据库访问的标准API&#xff08;应用程序编程接…

事务相关、不可重复读与幻读的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 事务内嵌套事务&#xff1a; 1) 都用spring事务时&#xff0c;取决spring采用的事务的隔离级别。 这个默认隔离级别是与具体的数据…

onload事件

onload事件它只支持少量标签<body>, <frame>, <iframe>, <img>, <input type"image">, <link>, <script>, <style> 不支持<div>,<p>标签等 所以&#xff0c;在div使用onload事件时该怎么办呢。。。转载…

Eclipse GBK批量转UTF-8插件(转)

最近需要把Android项目转Android Studio&#xff0c;由于之前是eclipse开发&#xff0c;而且坑爹的是编码还是GBK的&#xff0c;转到Android Studio中文都是乱码&#xff0c;如果一个文件一个文件ctrlc的话&#xff0c;想想就累&#xff0c;几经Google&#xff0c;发现一个很好…

网络爬虫--15.【糗事百科实战】多线程实现

文章目录一. Queue&#xff08;队列对象&#xff09;二. 多线程示意图三. 代码示例一. Queue&#xff08;队列对象&#xff09; Queue是python中的标准库&#xff0c;可以直接import Queue引用;队列是线程间最常用的交换数据的形式 python下多线程的思考 对于资源&#xff0…

浅谈:国内软件公司为何无法做大做强?

纵览,国内比较大的软件公司(以下统一简称"国软"),清一色都是做政府项目的(他们能做大的原因我就不用说了吧),真正能做大的国软又有几家呢?这是为什么呢? 今天风吹就给大家简单分析下: 1."作坊"式管理 "作坊"往往是效率最高的,国软几乎都是从作…

Java SE、Java EE、Java ME三者的区别

说得简单点 Java SE 是做电脑上运行的软件。 Java EE 是用来做网站的-&#xff08;我们常见的JSP技术&#xff09; Java ME 是做手机软件的。 1. Java SE&#xff08;Java Platform&#xff0c;Standard Edition&#xff09;。Java SE 以前称为 J2SE。它允许开发和部署在桌面、…

FileBeats安装

FileBeats安装 FileBeats官方下载链接&#xff1a; https://www.elastic.co/downloads/beats/filebeat 也可以直接使用以下命令下载&#xff08;文章下载目录一概为/home/tools, 解压后文件夹放到 /home/apps下&#xff09; wget https://artifacts.elastic.co/downloads/beats…

《程序员代码面试指南》第三章 二叉树问题 二叉树节点间的最大距离问题

题目 二叉树节点间的最大距离问题 java代码 package com.lizhouwei.chapter3;/*** Description:二叉树节点间的最大距离问题* Author: lizhouwei* CreateDate: 2018/4/16 19:33* Modify by:* ModifyDate:*/ public class Chapter3_20 {public int maxDistance(Node head) {int[…

MySQL中函数CONCAT及GROUP_CONCAT 对应oracle中的wm_concat

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、CONCAT&#xff08;&#xff09;函数 CONCAT&#xff08;&#xff09;函数用于将多个字符串连接成一个字符串。 使用数据表Info作为…

网络爬虫--16.BeautifulSoup4

文章目录一. BeautifulSoup4二. 解析实例三. 四大对象种类1. Tag2. NavigableString3. BeautifulSoup4. Comment四. 遍历文档树1.直接子节点 &#xff1a;.contents .children 属性1). .contents2). .children2. 所有子孙节点: .descendants 属性3. 节点内容: .string 属性五. …

Intel MKL 多线程设置

对于多核程序&#xff0c;多线程对于程序的性能至关重要。 下面&#xff0c;我们将对Intel MKL 有关多线程方面的设置做一些介绍&#xff1a; 我们提到MKL 支持多线程&#xff0c;它包括的两个概念&#xff1a; 1>MKL 是线程安全的&#xff1a; MKL在设计时&#xff0c;就保…