良好的并发编程习惯之封闭(Confinement)

创作内容丰富的干货文章很费心力,感谢点过此文章的读者,点一个关注鼓励一下作者,激励他分享更多的精彩好文,谢谢大家!


“共享可变状态”有两个要点:“共享”和“可变”。封闭的策略是:不共享就完事了。

《Java 并发编程实战》一书中列举了三种封闭的方式。

  • Ad-hoc 线程封闭
  • 栈封闭
  • ThreadLocal 类

Ad-hoc 封闭

"Ad-hoc" 一般指“特别的、专门的、临时的”等,在编程的语境中一般指“具体情况具体分析”。Ad-hoc 封闭也就指由程序自己实现的封闭。

例如有个 volatile 变量,在编写代码的时候,隐含实现了这样的约定:只有一个线程会“写”该变量,其它线程只会“读”操作。那么这种情况下这个“写线程”即使做了 "Check-then-Act" 操作也是线程安全的。

所以 Ad-hoc 封闭也只能是“具体情况具体分析”了。

栈封闭

局部变量(local variables)在方法调用时被分配到栈上,正常情况下当方法返回时就被销毁(不再被引用,可以被 GC 回收),只存在于调用的线程中。这些变量由于不会被共享,即使变量本身并不是线程安全的,也不用担心方法的线程安全性。

当然如果局部变量通过一些方式在方法调用结束后依旧被引用,则不再是“封闭”的,就会有线程安全的问题。如变量被作为方法的返回值被返回;被方法里创建的线程引用;引用被保存到了其它地方,如实例变量(instance variable)等。

一般如果一个方法只依赖它的输入参数和方法内创建的局部变量,不依赖其它的全局的信息,则可以说这个方法是“无状态”的。

ThreadLocal 类

ThreadLocal 也可以认为是前文所说的“线程安全类”,只不过 ThreadLocal 的语义上就是“线程封闭”的。

ThreadLocal 的作用是为每个线程保存一个副本,每个线程在调用 get 或 set 方法时都只会操作本线程的副本。由于每个线程只用自己的那份,不存在共享行为,因此是线程安全的。

一般来说,如果有一些对象从作用是可以做成单例,但它本身又不是线程安全的,就可以使用 ThreadLocal 为每个线程创建一个副本,就可以线程安全地把它作为单例使用了。

例如,我们知道 SimpleDateFormat 不是线程安全的,但是通过 ThreadLocal 的包装,就可以做到线程封闭,不在线程间共享,做到线程安全,如下示例:

public class DateUtil {private static ThreadLocal<SimpleDateFormat> dateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));public static String formatDate(Date date) throws ParseException {return dateFormat.get().format(date);}
}

要注意的是,由于需要为每个线程创建一个副本,如果初始化的代价比较高且经常性地创建新的线程,可能会有潜在的性能问题,虽然通常情况下不会成为问题。

另外,不要把从 ThreadLocal 获取的引用保存到其它地方,会有潜在的线程安全问题。

小结

封闭策略用人话来说就是:尽量不要用全局变量,如果全局变量是单例,考虑用 ThreadLocal 包装。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/479484.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

滚动的轮胎css3动画案例

目录 一、介绍 二、思路分析 三、轮胎制作 1.HTML代码 2.css 3.运行结果 四、轮胎动画 五、路的制作 1.HTML 2.css 六、运行结果 七、结束语 一、介绍 本节内容我们来制作一个轮胎滚动的案例&#xff0c;可以当作一个loading,其中我们的轮胎是纯css完成的&#xff0c;…

PointNet++论文复现

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

基础入门-Web应用架构类别源码类别镜像容器建站模版编译封装前后端分离

知识点&#xff1a; 1、基础入门-Web应用-搭建架构上的技术要点 2、基础入门-Web应用-源码类别上的技术要点 一、演示案例-架构类别-模版&分离&集成&容器&镜像 1、套用模版型 csdn / cnblog / github / 建站系统等 安全测试思路上的不同&#xff1a; 一般…

【JMeter性能测试框架篇】Win10下搭建JMeter+Influxdb+Grafana可视化性能测试监控平台

一、前言 平常使用jmeter进行性能测试时&#xff0c;工具自带的监控方式无法清晰直观的查看结果&#xff0c;给我们性能测试带来很多不便。因此我们需要搭建一个可视化性能测试监控平台来实时监控性能测试结果&#xff0c;这里我们采用JMeterInfluxdbGrafana开源免费框架来实现…

Qt桌面应用开发 第八天(综合项目一 飞翔的鸟)

目录 1.鸟类创建 2.鸟动画实现 3.鼠标拖拽 4.自动移动 5.右键菜单 6.窗口透明化 项目需求&#xff1a; 实现思路&#xff1a; 创建项目导入资源鸟类创建鸟动画实现鼠标拖拽实现自动移动右键菜单窗口透明化 1.鸟类创建 ①鸟类中包含鸟图片、鸟图片的最小值下标和最大值…

【Linux庖丁解牛】—软件安装vim!

目录 1、Linux中的软件安装 a、源码安装 b、软件包安装——rpm c、包管理器安装 包管理器的使用演示&#xff08;Ubuntu&#xff09; 2、Linux编辑器——vim 2.1 vim的基本概念 2.2 vim的基本操作 2.3 vim正常模式命令集 2.4 vim末行模式命令集 3、vim编辑器环境的一…

【数据结构与算法】排序算法总结:冒泡 / 快排 / 直接插入 / 希尔 / 简单选择 / 堆排序 / 归并排序

1 排序 1.1 冒泡 内排序的交换排序类别 1.1.1 普通实现 public class BubbleSort {/*** 基本的 冒泡排序*/public static void bubbleSort(int[] srcArray) {int i,j; // 用于存放数组下标int temp 0; // 用于交换数值时临时存放值for(i0;i<srcArray.length-1;i){// j …

如何构建SAAS项目

在后台使用JDBC方式动态创建用户输入的数据库信息&#xff08;库名、地址、用户名、密码&#xff09; 执行预先写好的sql文件&#xff08;如mybatis的scriptRunner)执行建表语句及插入基础数据&#xff08;管理员用户、普通用户&#xff09;

MQ高级2:MQ的可靠性

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

transformer学习笔记-神经网络原理

在深度学习领域&#xff0c;transformer可以说是在传统的神经网络的基础上发展而来&#xff0c;着重解决传统神经网络长距离关联、顺序处理、模型表达能力等问题。 在学习transformer之前&#xff0c;我想&#xff0c;有必要先对传统的神经网络做简要的了解。 一、神经网络基本…

【前端】JavaScript中的字面量概念与应用详解

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;字面量1. 数字字面量2. 字符串字面量3. 布尔字面量4. 空值字面量&#xff08;null&#xff09;5. 对象字面量6. 数组字面量7. 正则表达式字面量8. 特殊值字面量9. 函数字…

字节跳动青训营刷题笔记19

问题描述 小R正在组织一个比赛&#xff0c;比赛中有 n 支队伍参赛。比赛遵循以下独特的赛制&#xff1a; 如果当前队伍数为 偶数&#xff0c;那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛&#xff0c;且产生 n / 2 支队伍进入下一轮。如果当前队伍数为 奇数&…

Python中的简单爬虫

文章目录 一. 基于FastAPI之Web站点开发1. 基于FastAPI搭建Web服务器2. Web服务器和浏览器的通讯流程3. 浏览器访问Web服务器的通讯流程4. 加载图片资源代码 二. 基于Web请求的FastAPI通用配置1. 目前Web服务器存在问题2. 基于Web请求的FastAPI通用配置 三. Python爬虫介绍1. 什…

【ArcGISPro】使用AI提取要素-土地分类(sentinel2)

Sentinel2数据处理 【ArcGISPro】Sentinel-2数据处理-CSDN博客 土地覆盖类型分类 处理结果

WinForm 的Combox下拉框 在FlatStyle.Flat的边框设置

现象&#xff1a;Combox在设置FlatStyle.Flat时边框不见了 效果&#xff1a; 解决问题思路封装新控件&#xff1a; public class DBorderComboBox : ComboBox {private const int WM_PAINT 0xF;[Browsable(true)][Category("Appearance")][Description("边框…

Python 爬虫入门教程:从零构建你的第一个网络爬虫

网络爬虫是一种自动化程序&#xff0c;用于从网站抓取数据。Python 凭借其丰富的库和简单的语法&#xff0c;是构建网络爬虫的理想语言。本文将带你从零开始学习 Python 爬虫的基本知识&#xff0c;并实现一个简单的爬虫项目。 1. 什么是网络爬虫&#xff1f; 网络爬虫&#x…

使用UE5.5的Animator Kit变形器

UE5.5版本更新了AnimatorKit内置插件&#xff0c;其中包含了一些内置变形器&#xff0c;可以辅助我们的动画制作。 操作步骤 首先打开UE5.5&#xff0c;新建第三人称模板场景以便测试&#xff0c;并开启AnimatorKit组件。 新建Sequence&#xff0c;放入测试角色 点击角色右…

Uniapp 安装安卓、IOS模拟器并调试

一、安装Android模拟器并调试 1. 下载并安装 Android Studio 首先下载 Mac 环境下的 Android Studio 的安装包&#xff0c;为dmg 格式。 下载完将Android Studio 向右拖拽到Applications中&#xff0c;接下来等待安装完成就OK啦&#xff01; 打开过程界面如下图所示&#xf…

shell(5)字符串运算符和逻辑运算符

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

【金蝶双线指标】以看资金进出操作为主,兼顾波段跟踪和短线低吸

如上图&#xff0c;个股副图指标&#xff0c;大佬资金监控短线低吸攻击线操盘线趋势红蝴蝶&#xff0c;五大功能于一体。下面慢慢给大家仔细分享。 大佬资金监控指标&#xff0c;红绿进出&#xff0c;绿色缩小到极致&#xff0c;接近零轴&#xff0c;红绿柱分界线&#xff0c;为…