| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 并发编程基础五----构造并发布正确的对象 -> 正文阅读 |
|
[Java知识库]并发编程基础五----构造并发布正确的对象 |
前面讲了通过同步的方式可以安全的访问共享状态,并讲述了同步的几种方式。接下来两个内容将对《JAVA并发编程实战》中第三章对象的共享进行总结。 同步机制可以避免多个线程在同一时间访问相同的数据,对于共享变量来说如果被static修饰时是被分配到方法区中,被final修饰的静态变量是不可变的,这种本身就是线程安全的,如果没有被final修饰则在访问时需要通过同步方式保证其线程安全性,常用的方法有加锁和volatile两种方式,没被static修饰的变量在创建对象时存放在堆区中,依赖于对象的安全性。而在多线程里发布一个安全对象是要保证在发布的过程中创建一个完整的对象。 该部分主要包含两个部分: 1、对象的发布和逸出 2、发布对象的几种方式 3、另一种数据安全的共享方式 对象发布首先理解一下什么是对象发布 发布:在对象构建完成以后可以在当前代码之外的地方可以使用。主要是可以让其他类和线程可见 逸出:某个不该发布的对象发布了就是对象的逸出,比如说并发编程中如果不能保证安全的访问对象的情况下则在对象构造完成之前如果被发布出去了则说明该对象逸出了。 常用的发布对象的方式有以下几种 1、在对象构造完成后将对象的引用保存在一个共有的静态变量中。这样做的好处就是在发布一个对象的时候可能还会发布其他对象比如说非私有域中引用的所有对象。 举个例子说明以下: ????????比如说将一个对象存放在一个集合中,这样只要访问这个集合的其他类或者其他线程都可以看到这个对象的引用,但是这个只限定于对非private修饰的对象可以这样发布,如果是类的私有对象这样做就会导致这个对象逸出破坏了封装性,因为用private修饰的对象只限定于该类中可见,对其他类和线程是不可见的。 这里解释以下封装的主要原因:封装可以对简化对程序正确性的分析,并将private作用域作为一个约束防止无意中对作用域的破坏。
2、发布一个内部类实例。但这种方式需要注意一点,在发布时候防止外部类的this逸出。 因为在发布内部类时在外部封装的外部类实例也会被发布,但此时外部类还没有被初始化完成,这样就会导致对象逸出。因此为了避免这种方式的对象逸出必须避免在对象的构造过程中使this引用逸出。编程过程中就是避免在构造过程中启动一个线程,这样就不会看到一个不完整的对象。 举例: 不安全的方式
安全的发布一个对象的方式
3、安全的访问共享数据有两种方式:一种是之前讲过的通过同步的方式,第二种就是通过线程封闭的方式,即将每个线程使用共享数据的副本的形式或者每次只允许一个线程获取该对象。 线程封闭有以下三种方式: 第一种是Ad-hoc线程封闭 ? ? ? ? Ad-hoc线程封闭模式是通过设计一个特定职责的单线程的子系统来维护线程的封闭。 ? ? ? ?常见的采用这种模式的是安全的数据库连接池,让线程池来维护封闭性,连接池承接多个线程的访问,但每次只允许一个线程进入连接池获取connection对象,在该对象返回之前不允许其他线程进入线程池获取connection对象。 但这种线程封闭的方式比较脆弱,为什么脆弱?,看书上的解释是没有任何一种语言特性,但是太抽象了,不是很理解,有了解的同学可以一起探讨以下。 第二种是栈封闭的方式 栈封闭就是将基本类型的变量或者引用类型的变量设置为局部变量的方式,从而将其封装在线程中。 对于基本变量,由于其他线程用任何方法都不能获得这种类型的引用,而且其作用域只存在该变量所在的方法体中,因此对于局部基本变量,一直都是很安全的。 对于引用变量,一般是创建一个集合和一个实例对象,并将该实例对象的引用指向该集合,只要该集合的引用不被发布,就能确保这个实例对象的引用被封装在该线程中。 例子:
第三种方式就是使用TheadLoacl类 这种方式原理是将内存中的数据做n个副本,存储在线程局部的缓存中,在涉及到ThreadLocal的线程中使用该数据的副本,从而防止可变的单实例变量或全局变量共享。但过多的使用ThreadLocal对象会降低代码的可重用性,并增加了各类之间的耦合度。因此不能过多的使用。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 18:49:40- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |