本节主题:如果一个类是线程不安全的,但是又要在多线程程序中安全地使用,你该怎么办?

大体有两种思路:

第一种:确保该对象是能由单个线程访问,也就是这个对象是被封闭在线程中的;

第二种:通过锁来对该对象的访问进行保护。

实例封闭

封装简化了线程安全类的实现过程,提供了一种实例封闭机制(Instance Confinement)。

当一个对象被封装到另一个对象中时,能够访问被封装对象的所有的代码路径都是已知的,与不安全的类散落在整个程序中相比,更加易于分析。通过将封闭机制与合适的加锁策略结合起来,可以确保线程安全的方式来使用非线程安全的对象。

被封闭的对象一定不能超过既有的作用域,对象可以封闭在类的一个实例(作为私有成员);

或者封闭在某个作用域内(例如作为一个局部变量),再或者封闭在线程内(一个方法传到另一个方法中,而不是在多个线程中共享该对象)。

要注意,对象本身不会在发布的时候逸出。

私有一个对象;

控制该对象的访问路径;

加上适当的锁机制。

实例封闭是构建线程安全类的一个最简单的方式,它还使得在锁策略的选择上有了更多的灵活性。实例封闭可以使得不同的状态变量由不同的锁来保护,而其他形式的锁需要自始至终都用同一个锁。

Collections.synchronizedListy及其类似的方法,使得非线程安全的类可以在多线程环境中使用。这些工厂方法通过装饰器模式将容器类封装在一个同步的包装器对象中,而包装器对象能将接口中的每个方法都实现为同步方法,并将调用请求转发到底层的容器对象上。只要包装器对象拥有对底层容器对象的唯一引用(即把底层容器对象封闭在包装器中),那么它就是线程安全的。

Java监视器模式

Java监视器模式的对象会把对象的所有可变状态封装起来,并由对象自己的内置锁来保护。

使用私有锁对象而不是对象的内置锁(或其他任何可以通过共有方式访问的锁),有许多优点。私有的锁对象可以将锁封装起来,使客户端无法得到锁。

Java并发编程(十一)实例封闭的更多相关文章

  1. Java并发编程:线程封闭和ThreadLocal详解

    转载请标明出处: http://blog.csdn.net/forezp/article/details/77620769 本文出自方志朋的博客 什么是线程封闭 当访问共享变量时,往往需要加锁来保证数 ...

  2. 《java并发编程实战》读书笔记2--对象的共享,可见性,安全发布,线程封闭,不变性

    这章的主要内容是:如何共享和发布对象,从而使它们能够安全地由多个线程同时访问. 内存的可见性 确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化. 上面的程序中NoVisibility可能 ...

  3. Java并发编程(十一)-- Java中的锁详解

    上一章我们已经简要的介绍了Java中的一些锁,本章我们就详细的来说说这些锁. synchronized锁 synchronized锁是什么? synchronized是Java的一个关键字,它能够将代 ...

  4. Java并发编程原理与实战三十一:Future&FutureTask 浅析

    一.Futrue模式有什么用?------>正所谓技术来源与生活,这里举个栗子.在家里,我们都有煮菜的经验.(如果没有的话,你们还怎样来泡女朋友呢?你懂得).现在女票要你煮四菜一汤,这汤是鸡汤, ...

  5. Java并发编程原理与实战十一:锁重入&自旋锁&死锁

    一.锁重入 package com.roocon.thread.t6; public class Demo { /* 当第一个线程A拿到当前实例锁后,进入a方法,那么,线程A还能拿到被当前实例所加锁的 ...

  6. java并发编程笔记(十一)——高并发处理思路和手段

    java并发编程笔记(十一)--高并发处理思路和手段 扩容 垂直扩容(纵向扩展):提高系统部件能力 水平扩容(横向扩容):增加更多系统成员来实现 缓存 缓存特征 命中率:命中数/(命中数+没有命中数) ...

  7. Java并发编程 | 从进程、线程到并发问题实例解决

    计划写几篇文章讲述下Java并发编程,帮助一些初学者成体系的理解并发编程并实际使用,而不只是碎片化的了解一些Synchronized.ReentrantLock等技术点.在讲述的过程中,也想融入一些相 ...

  8. Java并发编程原理与实战二十一:线程通信wait&notify&join

    wait和notify wait和notify可以实现线程之间的通信,当一个线程执行不满足条件时可以调用wait方法将线程置为等待状态,当另一个线程执行到等待线程可以执行的条件时,调用notify可以 ...

  9. Java并发编程实战.笔记十一(非阻塞同步机制)

    关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...

  10. 《Java并发编程实战》学习笔记 线程安全、共享对象和组合对象

    Java Concurrency in Practice,一本完美的Java并发参考手册. 查看豆瓣读书 推荐:InfoQ迷你书<Java并发编程的艺术> 第一章 介绍 线程的优势:充分利 ...

随机推荐

  1. 【棋盘DP】【OpenJudge7614】最低通行费

    最低通行费 总时间限制: 1000ms 内存限制: 65536kB [描述] 一个商人穿过一个 N*N 的正方形的网格,去参加一个非常重要的商务活动.他要从网格的左上角进,右下角出.每穿越中间1个小方 ...

  2. golang垃圾回收

    常见GC算法 我总结了一下常见的 GC 算法.分别是:引用计数法.Mark-Sweep法.三色标记法.分代收集法. 1. 引用计数法 原理是在每个对象内部维护一个整数值,叫做这个对象的引用计数,当对象 ...

  3. VHDL硬件描述语言实现数字钟

    --VHDL上机的一个作业,程序太长实验报告册上写不下了.于是就在博客上留一份吧.LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOG ...

  4. HttpClient 处理中文乱码

    HttpClient 请求的中文乱码问题 相关类库: commons-codec-1.3.jar,commons-httpclient-3.1.jar,commons-logging-1.1.1.ja ...

  5. 关于css解决俩边等高的问题(等高布局)

    等高布局 前段时间公司需哦一个后台管理系统,左侧是导航栏,右侧是content区域.然厚刚开始用的是js 去控制的,但是当页面的椰蓉过长的时候,有与js单线程,加载比较慢,就会有那么一个过程,查找了很 ...

  6. centos7 iptables和firewalld学习记录

    centos7系统使用firewalld服务替代了iptables服务,但是依然可以使用iptables来管理内核的netfilter 但其实iptables服务和firewalld服务都不是真正的防 ...

  7. D3.js系列——元素操作和简单画布操作

    一.元素操作: 1.选择元素 select 和 selectAll,以及选择集的概念 var p = d3.select("body").select("p") ...

  8. 配置composer全量镜像与主要命令

    配置中国全量镜像 查看当前composer配置的镜像地址 composer config -g repo.packagist 显示如下,显示说明没有配置镜像地址 接下来我使用下面的命令进行查看配置的镜 ...

  9. 【转】Spring Annotation 详解

    (1) .<context:component-scan base-package="*.*" /> 该配置隐式注册了多个对注解进行解析的处理器,如: Autowire ...

  10. 微信小程序页面跳转

    一:跳转的数据传递 例如:wxml中写了一个函数跳转: [html] view plain copy <view class="itemWeight" catchtap=&q ...