前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java concurrency in practice笔记 02 03

Java concurrency in practice笔记 02 03

作者头像
Dylan Liu
发布2019-07-01 11:43:43
3580
发布2019-07-01 11:43:43
举报
文章被收录于专栏:dylanliudylanliu

什么是线程安全性

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

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

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

竞态条件(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的实例。

代码语言:javascript
复制
class Escape{
    private  Set<Secret> set;
    public getSet(){
         return set;
    }
}

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

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档