文档章节

Java concurrency in practice笔记 02 03

52iSilence7
 52iSilence7
发布于 2014/06/04 21:22
字数 1064
阅读 35
收藏 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()方法,构造函数中只初始化值,不启动线程,需要增加一个内部类和私有变量保存要启动的线程对象。

© 著作权归作者所有

共有 人打赏支持
上一篇: spring BeanFactory
下一篇: Linux 各种$或命令
52iSilence7
粉丝 4
博文 69
码字总数 50566
作品 0
海淀
高级程序员
私信 提问
111 多线程JUC包下代码分析

Java多线程系列目录(共43篇) AtomicLongFieldUpdater:通过反射+CAS实现对传入对象的指定long字段实现类似AtomicLong的操作 http://www.cnblogs.com/skywang12345/p/javathreadscategory.ht...

素雷
2017/10/31
0
0
读《深入理解Java虚拟机》- 笔记08

《深入理解Java虚拟机:JVM高级特性与最佳实践》第2版 第10章 早期(编译期)优化 59. 语法糖 在计算机语言中添加某种语法,对语言的功能没有影响,但是方便开发人员使用。 泛型是一种语法糖...

阿历Ali
08/18
0
0
JNI Kickstart 小结 02 :桥接至与 Java 无关的纯本地库

JNI 程序小结 02 :桥接至与 Java 无关的纯本地库Java + JNI 桥接库 + 纯本地库 异构程序构建示例。 上文: http://my.oschina.net/typhoon/blog/405527 本文为“加强版”。 编写 Java 程序:...

自由狼-台风
2015/06/25
0
1
JAVA区块链项目实战视频课程

课程介绍 全国首套,基于java的区块链实战教程。目的是让更多的java编程者了解区块链,掌握区块链开发。 1、区块链理论:以node.js例子区块链原理有深刻理解; 2、区块链java实战:深刻理解区...

小红牛
09/14
0
0
android中用Spannable在TextView中设置超链接、颜色、字体

昨晚研读 ApiDemo 源码至 com.example.android.apis.text.Link 类。首先,看一下其运行效果:   要给 TextView 加上效果,方式主要有几种:   第一种,自动应用效果,使用 android:auto...

顶层设计
2012/09/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

阿里云建站

阿里云自营建站 没想到阿里云已经切入这块市场了。可以用拖动的方式来建站的模式,真的还是6.

miaojiangmin
24分钟前
2
0
linux系统top命令:virt,res,shr详解

VIRT:virtual memory usage 虚拟内存 1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等 2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用...

刘祖鹏
30分钟前
2
0
day154-2018-11-21-英语流利阅读-待学习

快手网红发明家:百万粉丝 vs 零销量 雪梨 2018-11-21 1.今日导读 “我做了一个‘雷神锤’的斜挎包,你看这里可以打开,里面可以装手机、卫生纸、钱包,觉得轻的话可以放一些砖头。咱们把它背...

飞鱼说编程
37分钟前
10
0
图灵奖得主华人高徒发布AI芯片!64位RISC-V、高度可编程,低功耗

作为RISC-V架构下的旗手玩家,睿思芯科自然希望通过产品展现出RISC-V可编程架构的巨大潜力。 https://mbd.baidu.com/newspage/data/landingshare?context=%7B%22nid%22:%22news_917924603675...

whoisliang
37分钟前
4
0
xcode 10 缺少 libstdc++6.0.9 解决方案

image.png 本方案基于xcode10正式版操作,其它版本请自行验证! 苹果在XCode10中移除了libstdc++(libstdc++.6、libstdc++6.0.9)库。 项目解决方法:删除libstdc++(libstdc++.6、libstdc++6....

壹峰
41分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部