文档章节

Java concurrency in practice笔记 02 03

Quan全
 Quan全
发布于 2014/06/04 21:22
字数 1064
阅读 34
收藏 0
点赞 0
评论 0

 什么是线程安全性

        线程安全性的核心是正确性,正确性的含义是如果类的行为与其规范完全一致。因此当多个线程访问某个类时,类的行为始终是安全的,这个类就是线程安全的,这个类也就是一个线程安全类。

        如果一个类没有成员变量,所有的状态都是在线程栈中存储使用的,不会与其他的线程发生数据交互,也就不会出现冲突,这个类是线程安全的。

        如果一个线程要与其他线程共享某个类的变量,这个类需要对共享变量进行同步管理才能保证这个类是线程安全的。

竞态条件(race condition):线程执行结果的正确性取决于执行顺序。

        有check-then-act 和 read-modify-write几种情况,由于操作时非原子性的,这种依赖于以前的结果来进行后续的操作是不安全的,多个线程可能同时check,或有的线程在其他线程check之后act之前对条件进行了修改,就会导致某一次的修改被覆盖,如果用这种方式来生成unique id,就可能导致系统崩溃。

线程安全性有两个方面:原子性和可见性

        上面竞态条件的产生就是因为check-then-act不是原子性操作造成的。可以使用java内置的synchronized关键字加锁,使操作变成原子操作,但是当在有多个共享变量的时候需要注意所有的变量需要持有同一个同步锁,否则会出问题。

        可见性:每个线程执行期间都有自己的线程栈,线程是看不到其他线程的栈内东西的,线程在从主内存读入数据后会在栈内保存一个副本,在线程退出之前会将值写回主内存。这导致的一个问题就是某个线程修改了共享变量的值,另一个线程根据共享变量的值来决定下一步的走向,但是这个线程修改了共享变量的值后对另一个线程是不可见的,这就可能导致另一个线程一直等待。

volatile关键字

        volatile关键字可以保证共享变量的可见性,但不能保证原子性,synchronized关键字两者都能保证。volatile保证线程读到的共享变量的值都是最新的,也就是说volatile修饰的变量是会实时写回主内存中的。volatile提供了比较弱的同步机制,当变量声明为volatile类型后 编译器与运行时会注意到变量是共享的,不会将该变量上的操作与其他内存操作一起重新排序。使用也有限制:对变量的写入操作不能依赖当前值,该变量不会与其他变量一起纳入不变性条件中,在访问变量时不需要加锁。

发布(publish)与逸出(escape)

        发布是指使对象能在当前作用域外的代码中使用,而当 一个不该发布的对象却发布的时候,就产生了逸出。

     下面的get方法就将私有变量泄露出去了,而Secret也被泄露出去,因为可以通过枚举得到每个Secret的实例。  

class Escape{
    private  Set<Secret> set;
    public getSet(){
         return set;
    }
}

        比较难理解的是this逸出,看下面的例子

class ThisEscape{
    ThisEscape(){
       new Thread(new Runnable(){
             public void run(){
                this.s="1";//在类的构造函数还没有完成的时候就调用实例,this就发生了逸出,会产生无                           //法预料的后果
             }
       }).start();
    }
    private String s;
}



        解决办法就是增加一个init()方法,构造函数中只初始化值,不启动线程,需要增加一个内部类和私有变量保存要启动的线程对象。

© 著作权归作者所有

共有 人打赏支持
Quan全
粉丝 1
博文 45
码字总数 37262
作品 0
海淀
高级程序员
JAVA使用字节流将本地图片传到前端

JAVA使用字节流将本地图片传到前端 01.基本介绍 在我们日常的开发中,会遇到对验证码的使用问题(验证码的作用这里不多多说,避免程序被恶意攻击等),如何是的前端和后端保持一致是一个问题...

meiqi0538 ⋅ 04/09 ⋅ 0

1、Java并发性和多线程-并发性和多线程介绍

以下内容转自http://ifeve.com/java-concurrency-thread/: 在过去单CPU时代,单任务在一个时间点只能执行单一程序。之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程。虽...

easonjim ⋅ 2017/06/14 ⋅ 0

Guava 25.1 发布,Google 的 Java 核心工具库

Guava 25.1 已发布,更新如下: Switched to the type annotation version of in the JRE/Java 8 flavor. : Added , copied from . : Added Token Binding HTTP headers to . : Added overr......

王练 ⋅ 05/24 ⋅ 0

Java 使用 happen-before 规则实现共享变量的同步操作

前言 熟悉 Java 并发编程的都知道,JMM(Java 内存模型) 中的 happen-before(简称 hb)规则,该规则定义了 Java 多线程操作的有序性和可见性,防止了编译器重排序对程序结果的影响。按照官方的...

stateIs0 ⋅ 01/20 ⋅ 0

从Java小白到架构师必须要看的书籍,真正的“武林秘籍”!

少年,我看你骨骼精奇,将是未来万中无一的IT精英,很是适合学JAVA。维护世界和平就看你的了,我这里有能让你成为IT精英的办法!还不来看看! 基础类 1、《Thinking in Java》,入门第一位是...

启示录是真的 ⋅ 05/25 ⋅ 0

JavaWeb07-HTML篇笔记(二)

1.1 案例一:使用JDBC完成CRUD的操作:1.1.1 需求: 对分类管理使用JDBC进行CRUD的操作. 1.1.2 分析:1.1.2.1 技术分析: 【JDBC的概述】 Ø JDBC:Java DataBase Connectivity Java数据库的连...

我是小谷粒 ⋅ 05/16 ⋅ 0

java.sql.date与java.util.date区别以及数据库中插入带时分秒的时间

java.sql.Date,java.sql.Time和java.sql.Timestamp三个都是java.util.Date的子类(包装类)。 java.sql.Date是java.util.Date的子类,是一个包装了毫秒 值的瘦包装器,允许 JDBC 将毫秒值标识...

村长大神 ⋅ 2015/02/02 ⋅ 0

Spring-Batch处理MySQL数据后存到CSV文件

1 介绍 用Spring Batch实现了个简单的需求,从MySQL中读取用户表数据,根据生日计算年龄,将结果输出到csv文件。 1.1 准备表及数据 2 实现 2.1 项目目录 2.2 实体类 2.3 ItemReader TestUse...

yysue ⋅ 05/26 ⋅ 0

小白用IntelliJ IDEA无脑搭建Spring Boot工程

这里不讲解什么是spring,什么是spring boot。只需要知道这是一个目前比较流行的java后端框架,而作为入门者,前期只需要依葫芦画瓢,利用idea搭建spring boot 的hello world工程。 01 Intel...

Sunny玄子 ⋅ 05/20 ⋅ 0

深入理解JVM学习笔记(一、总览)

1、JVM历史 2、JVM内存结构 3、JVM垃圾回收机制 4、JVM性能监控工具 5、JVM性能调优案例时间 6、JVM类文件结构 7、JVM类加载机制 8、JVM字节码执行引擎 9、JVM虚拟机编译及其运行时优化 10、...

jintaohahahaha ⋅ 05/28 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

10个免费的服务器监控工具

监控你的WEB服务器或者WEB主机运行是否正常与健康是非常重要的。你要确保用户始终可以打开你的网站并且网速不慢。服务器监控工具允许你收集和分析有关你的Web服务器的数据。 有许多非常好的服...

李朝强 ⋅ 30分钟前 ⋅ 0

压缩工具之zip-tar

zip 支持目录压缩。使用yum安装zip包,使用yum安装unzip包 zip 1.txt.zip 1.txt #将1.txt文件压缩,新生成的压缩文件为1.txt.zip,原文件保留 zip -r 123.zip 123/ #-r对目录操作。将123/目录...

ZHENG-JY ⋅ 31分钟前 ⋅ 0

Dubbo @Activate注解使用和实现解析

Activate注解标识一个扩展是否被激活和使用,可以放在定义的类上和方法上,dubbo用它在SPI扩张类定义上,标识这个扩展实现激活的条件和时机,先看下定义: /** * Activate * <p/> * ...

哲别0 ⋅ 37分钟前 ⋅ 0

6.5 zip压缩工具 tar打包 打包并压缩

1.tar tar命令格式 [-zjxcvfpP] filename tar -z:表示同时用gzip压缩。 -j:表示同时用bzip2压缩。 -J:表示同时用xz压缩。 -x:表示解包或者解压缩。 -t:表示查看tar包里的文件。 -c:表示建...

oschina130111 ⋅ 39分钟前 ⋅ 0

Linux系统工程狮养成记

如今的社会,随着时代的发展,出现了很多职业,像电子类,计算机类的专业,出现了各种各样的工程师,有算法工程师,java工程师,前端工程师,后台工程师,Linux工程师,运维工程师等等,不同...

六库科技 ⋅ 46分钟前 ⋅ 0

Linux 机器的渗透测试命令备忘表

如下是一份 Linux 机器的渗透测试备忘录,是在后期开发期间或者执行命令注入等操作时的一些典型命令,设计为测试人员进行本地枚举检查之用。 此外,你还可以从这儿(https://gbhackers.com/c...

寰宇01 ⋅ 47分钟前 ⋅ 0

windows 安装java开发环境,配置jdk

下载jdk安装文件 链接:https://pan.baidu.com/s/1UEKPjnAdMqNj612B39Pfsg 密码:ipqx 如果javac无法使用 1,检查环境变量名称中是否有空格。。。,去除后即可 2,将JAVA_HOME替换为原始路径...

阿豪boy ⋅ 49分钟前 ⋅ 0

简析log4j的实现方式

刚加入新公司,对日志的要求比较严格,对此特意花了几天时间看了一下log4j的源码,大概了解了一下log4j的实现方式,总结如下: log4j的实现分为两个步骤:log4j.xml的加载,logger的使用 这里...

zdatbit ⋅ 今天 ⋅ 0

win环境下jdk7与jdk8共存配置

1.jdk安装包 jdk安装包 安装步骤略 2.jdk等配置文件修改 在安装JDK1.8时(本机先安装jdk1.7再安装的jdk1.8),会将java.exe、javaw.exe、javaws.exe三个文件copy到了C:\Windows\System32,这...

泉天下 ⋅ 今天 ⋅ 0

windows profesional 2017 build problem

.net framework .... https://stackoverflow.com/questions/43330915/could-not-load-file-or-assembly-microsoft-build-frameworkvs-2017...

机油战士 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部