线程封闭&栈封闭

Java并发编程--线程封闭(Ad-hoc、栈、ThreadLocal) 线程封闭(Thread Confinement):仅在单线程内访问数据,不需要同步。 常见应用是:JDBC(Java Database Connectivity)的Connection对象。 1.Ad-hoc线程封闭  指维护线程封闭性的职责完全由程序实现来承担。Ad-hoc线程封闭是非常脆弱的,因为没有任何一种语言特性,例如可见性修饰符或局部变量,能将对象封闭到目标线程上。  当决定使用 阅读详情

一 概述

当访问共享数据的可变数据时,通常需要使用同步。一种避免使用同步的方式就是不共享数据。如果仅在单线程内访问数据,就不需要同步。这种技术被称为线程封闭(Thread Confinement),它是实现线程安全的最简单的方式之一。当某个对象封闭在一个线程之中时,这种用法将自动实现线程安全性,即使被封闭的对象本身不是线程安全的。

在Swing中大量的使用线程封闭技术。Swing的可视化组件和数据模型对象都不是线程安全的,Swing通常将它们封闭到Swing的事件分发线程中来实现线程安全性。要想正确地使用Swing,那么在除了事件线程之外的其他线程中就不能访问这些对象(为了进一步简化对Swing的使用,Swing还提供了invokerLater机制,用于将一个Runnable实例调度到事件线程中执行)。Swing应用程序的许多并发错误都是由于错误地在另一个线程中使用了这些封闭的对象。

线程封闭技术的另一种常见应用是JDBC(Java DataBase Connectivity)的Connection对象。JDBC规范并不是要求Connection对象必须是线程安全的。在典型的服务器应用程序中,线程从线程池中获取一个Connection对象,并且用该对象来处理请求,使用完后再将对象返还给连接池。由于大多数请求(例如Servlet请求或者EJB调用等)都是由单个线程采用同步的方式来处理,并且再Connection对象返回之前,连接池不会再将它分配给其他线程,因此着这中线程管理模式在处理请求时隐含地将Connection对象封闭在线程中。

在Java语言中并没有强制规定某个变量必须由锁来保护,同样在Java语言中也无法强制将对象封闭在某个线程中。线程封闭是在程序设计中的一个考虑因素,必须在程序中实现。Java语言及其核心库提供了一些机制来帮助维持线程的封闭性,例如局部变量和ThreadLocal类,但即使如此,程序员任然需要负责确保封闭咋线程中的对象不会从线程中逸出。

二 Ad-hoc线程封闭

Ad-hoc线程封闭是指,维护线程封闭性的职责完全由程序实现来承担。Ad-hoc线程封闭式非常脆弱的,因为没有任何一个语言特性,例如可见性修饰符或局部变量,能将对象封闭到目标线程上。事实上,对线程封闭对象(例如,GUI应用程序中的可视化组件或数据模型等)的引用通常保存在共有变量中。

当决定使用线程封闭技术时,通常是因为要将某个特定的子系统实现为一个单线程子系统。在某种情况下,单线程子系统提供的简便性要胜过Ad-hoc线程封闭技术的脆弱性。

在volatile变量上存在一种特殊的线程封闭。只要你能确保只有单个线程对共享的volatile变量执行写入操作,那么就可以安全地在这些共享的volatile变量上执行"读取-修改-写入"的操作。在这中情况下,相当于将修改操作封闭在单个线程中以防止发生竞态条件,并且volatile变量的可见性保证还确保了其他线程能看到最新的值。

应用程序服务器提供的连接池是线程安全的,连接池通常会由多个线程同时访问,因此非线程安全的连接池是毫无意义的。

使用单线程子系统的另一个原因是为了避免死锁,这也是大多数GUI框架都是单线程的原因。

由于Ad-hoc线程封闭技术的脆弱性,因此在程序中尽量少用它,在可能的情况下,应该使用更强的线程封闭技术(如,栈封闭或ThreadLocal类)

三 栈封闭

栈封闭式线程封闭的一种特例,在栈封闭中,只能通过局部变量才能访问对象。正如封装能使得代码更容易维持不变性条件一样,同步变量也能使对象更易于封闭在线程中。局部变量的固有属性之一就是封闭在执行线程中。它们为执行线程的栈中,其他线程无法访问这个栈。栈封闭(也被称为线程内部使用或者线程局部使用,不要与核心类库中的ThreadLocal混淆),它比Ad-hoc线程封闭更易维护,也更加健壮。

public class StackClose {

    public int loadTheArk(Collection<com.TWO.Boy> canditates) {
        SortedSet<com.TWO.Boy> boys;
        int numPairs = 0;
        com.TWO.Boy canditate = null;

        //boys被封闭在方法中,不要使它们逃逸
        boys = new TreeSet<com.TWO.Boy>();
        boys.addAll(canditates);
        for(com.TWO.Boy boy : boys){
            if(canditate == null) {
                canditate = boy;
            }else {
                ++numPairs;
            }
        }
        return numPairs;
    }
}

对于基本的局部变量,如loadTheArk方法中的numPairs,无论如何都不会破坏栈封闭性。由于任何方法都无法获得对基本类型的引用,因此Java语言的这种语义就确保了基本类型的局部变量始终封闭在线程中。

在维持对象引用的栈封闭性时,程序员需要多做一些工作以确保被引用的对象不会逸出。在loadTheArk中实例化一个TreeSet对象,并将指向该对象的一个引用保存到boys中。此时,只有一个引用指向集合boys,这个引用被封闭在局部变量中,因此也被封闭在执行线程中。然而,如果发布了对集合boys(或者该对象中的任何内部数据)的引用。那么封闭性将被破坏,并导致对象boys的逸出。

如果在线程内部(Within-Thread)上下文中使用非线程安全的对象,那么该对象仍是线程安全的,然而,要小心的是,只有编码人员才知道哪些对象需要被封闭到执行线程中,以及被封闭的对象是否是线程安全的。如果没有明确地说明这些需求,那么后续的维护人员很容易错误地使对象逸出。

【java高性能编程基础】 - 线程封闭与ThreadLocal源码分析 文章目录线程封闭的概念ThreadLocal解析ThreadLocal类的定义ThreadLocal类中提供的方法构造方法成员方法ThreadLocal示例 线程封闭的概念 在多线程访问共享可变数据时,就会涉及到线程间数据同步的问题。如果数据都被封闭在各自的线程之中,就不需要同步了,也不会出现线程安全的问题了。这种通过将数据封闭在线程中而避免使用同步的技术就叫线程封闭。 实现线程封闭的方法有多种,比如 ad-hoc线程封闭 局部变量 ThreadLocal ThreadLocal解析 ThreadLoc 阅读详情

相关推荐

java线程封闭之栈封闭和ThreadLocal

主要介绍了java线程封闭之栈封闭和ThreadLocal,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

什么是栈封闭?什么情况下对象引用的栈封...

1. 什么是栈封闭?   答:栈封闭是线程封闭的一种特例,在栈封闭中,只能通过局部变量才能访问对象。它们位于执行线程的栈中,其他线程无法访问这个栈。“栈封闭”是实现“线程封闭”的机制之一,而“线程封闭”和线程安全性相关。   2. 什么情况下对象引用的栈封闭性会被破坏”,破坏掉的后果是什么?   答: 1     private ArrayList&lt;Animal&gt; animals; /...

黑马程序员广州中心的专栏 706

技术解析:PETR如何通过3D位置编码革新多视角3D目标检测

本文深入解析了PETR模型如何通过创新的3D位置编码技术革新多视角3D目标检测。它摒弃了DETR3D复杂的投影采样机制,通过3D坐标生成器和编码器,将3D几何信息直接注入2D图像特征,构建出3D感知特征。该方法简化了流程,提升了模型对空间关系的理解能力与训练稳定性,为自动驾驶等领域的精准感知提供了新思路。

weixin_29079743的博客 212

栈封闭java

栈封闭式线程封闭的一种特例,在栈封闭中,只能通过局部变量才能访问对象,局部变量固有的属性就是封闭在执行线程当中,位于执行栈中,其他线程无法访问该栈,栈封闭不同于核心类库当中的ThreadLocal,比ad-hoc线程封闭更容易维护,更加健壮 //基本类型的局部变量与引用变量的线程封闭性 public int loadTheArk(Collection&lt;Animal&gt; candidates){ SortedSet&lt;Animal&gt; animals; int numPairs =

weixin_37632716的博客 354

NXP S32K3xx 多次复位(reset)后MCU跑死、崩溃、出错分析

s32k3出现多次复位后死机的情况

HeFlyYoung的博客 9513

别再死记公式了!用HFSS/CST手把手教你仿真一个2.4GHz WiFi的PIFA天线(附参数调试技巧)

本文详细介绍了使用HFSS和CST仿真软件设计2.4GHz WiFi PIFA天线的全流程,包括建模准备、分步操作指南和参数调试技巧。通过可视化结果和实战案例,帮助工程师快速掌握天线设计的关键参数优化方法,提升辐射性能和工作效率。

weixin_31682031的博客 331

java 多线程 栈_java线程封闭之栈封闭和ThreadLocal

线程封闭在多线程的环境中,我们经常使用锁来保证线程的安全,但是对于每个线程都要用的资源使用锁的话那么程序执行的效率就会受到影响,这个时候可以把这些资源变成线程封闭的形式。1、栈封闭所谓的栈封闭其实就是使用局部变量存放资源,我们知道局部变量在内存中是存放在虚拟机栈中,而栈又是每个线程私有独立的,所以这样可以保证线程的安全。2、ThreadLocal我们先看ThreadLocal和线程Thread的关...

weixin_28695537的博客 320

nacos3.1.0适配国产数据库

Nacos 3.1.0适配国产数据库指南 本文介绍了Nacos 3.1.0版本适配达梦数据库和人大金仓数据库的具体步骤。主要内容包括:添加达梦和人大金仓的JDBC驱动依赖,修改nacos-persistence模块的配置文件及相关Java类,以及打包和运行注意事项。文章特别指出3.1.0版本需要JDK17环境,并提供了解决常见问题的建议,如添加VM options配置和不同启动方式等。通过本文的配置指导,可以实现Nacos服务在国产数据库环境下的正常运行。

梦昼初的博客 1463

【Java开发300个实用技巧】85.线程封闭栈封闭与ThreadLocal

本文深入探讨了Java中的无锁编程技术CAS(Compare And Swap),并提供了实战应用和优化策略。CAS是一种CPU级别的原子操作,通过“预期值-新值”的比对机制实现无锁并发控制。文章详细解析了CAS的原理、原子类Atomic的应用、ABA问题及解决方案、性能优化技巧以及适用场景。通过对比不同实现方案的性能数据,展示了CAS在高并发计数场景中的优势。最后,强调了CAS虽为利器,但并非万能,需根据具体场景灵活选择同步机制。本文为Java开发者提供了一套完整的无锁编程指南,帮助他们在高并发环境下优雅

888

物联网技术-第2章-物联网技术架构

• 物联网具有很强的异构性• 为实现异构设备之间的互联、互通与互操作,物联网需要以一个开放的分层的可扩展的为框架。

m0_73804764的博客 2976

Python从0到100(十九):Python标准库初探

哈希函数又称哈希算法或散列函数,是一种为已有的数据创建“数字指纹”(哈希摘要)的方法。哈希函数把数据压缩成摘要,对于相同的输入,哈希函数可以生成相同的摘要(数字指纹),需要注意的是这个过程并不可逆(不能通过摘要计算出输入的内容)。举一个简单的例子,用户注册时我们希望在数据库中保存用户的密码,很显然我们不能将用户密码直接保存在数据库中,这样可能会导致用户隐私的泄露,所以在数据库中保存用户密码时,通常都会将密码的“指纹”保存起来,用户登录时通过哈希函数计算密码的“指纹”再进行匹配来判断用户登录是否成功。

拥有百余位万粉技术博主、200余位可合作代发博主,私域技术社群规模达千人,商务合作私信 5002

1.1.6 线程封闭

它是一个线程级别变量,每个线程都有一个ThreadLocal就是每个线程都拥有了自己独立的一个变量竞争条件被彻底消除了,在并发模式下是绝对安全的变量。并不是所有时候,都要用到共享数据,所以线程封闭概念就提出来了。数据都被封闭在各自的线程之中,就不需要同步,这种通过将数据封闭在线程中而避免使用同步的技术称为线程封闭。可以用ThreadLocal存储一些参数,以便在线程中多个方法中使用,用来代替方法传参的做法。会自动在每一个线程上创建一个T的副本,副本之间彼此独立,互不影响。的固有属性之一就是封闭在线程中。

qq_34504086的博客 113

Python爬虫实战:使用最新技术爬取新浪新闻首页数据

本文详细介绍了三种爬取新浪新闻首页的技术方案,从简单的requests-html到强大的Playwright,再到分布式Scrapy架构。小规模爬取:requests-html或aiohttp方案需要JavaScript渲染:Playwright方案大规模分布式爬取:Scrapy-Redis方案。

2201_76125261的博客 1243

什么是“线程封闭”?

为了确保线程的安全,通常需要保证可变的共享数据的同步访问,具体采用的方式有很多;但还有一种方法可以保证线程的安全,即是使可变数据不共享,或者是使数据不可变。所谓“线程封闭”即是仅在单线程中访问数据,也就是通过让可变数据不被多个线程共享以确保数据的正确性。 栈封闭 局部变量在函数的作用域当中,只有该函数本身可以访问,因此,也就自然地保证了线程的安全性。这就是线程封闭中的“栈封闭”。举例如下所示。...

dengwenjieyear的博客 1886

SOME/IP协议详解「1.1·面向服务与面向信号」

面向信号和面向服务的区别,和举例子

雪云飞星的博客 5654

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

源码|从串行线程封闭到对象池、线程池

相对于线程封闭,串行线程封闭离用户的距离更近一些,简单灵活,实用性强,很容易掌握。而线程封闭更多沦为单纯的设计策略,单纯使用线程封闭的场景不多。线程池与串行线程封闭、对象池的关系不大,但经常被混为一谈;没看过源码的很难想到其实现方案,面试时也能立分高下。线程池的实现很有意思。在追源码之前,猴子一直以为线程池就是把线程存起来,用的时候取出来执行任务;看了源码才知道实现如此之妙,简洁优雅效率高。源码才是最好的老师。原文地址:源码|从串行线程封闭到对象池、线程池。

攻城狮不是猫 984

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

多线程理解(六) 线程封闭

一、什么是线程封闭:就是把对象封闭到一个线程里,只有这一个线程能够看到此对象。那么就算是这个对象不是线程安全的也不会出现不安全的问题,这就是线程封闭。 二、实现线程封闭的方法:         1.Ad-hoc线程封闭 这是完全靠实现者控制的线程封闭,他的线程封闭完全靠实现者实现,是最糟糕的一种线程封闭。         2.栈封闭 栈封闭是我们最经常遇到的一种线程封闭。栈封闭就是指局部...

linjiaen20的博客 373

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Java - 线程封闭

保证并发安全性的方式有三: 不共享、不可变、同步 前两种方式相对第三种要简单一些。 这一篇不说语言特性和API提供的相关同步机制,主要记录一下关于共享的一些思考。 共享(shared),可以简单地认为多个线程可以同时访问某个对象。 如果仅仅在单线程内进行访问则不存在同步的问题。 保证数据的单线程访问称为线程封闭(thread confinement)。 线程封...

aozhangping6851的博客 83

从线程封闭到 ThreadLocal:理解并发中的私有空间

本文探讨了并发编程中的线程封闭技术及其实现方式。线程封闭通过将数据限制在单个线程中访问,避免了同步开销,是最简单的线程安全策略之一。文章介绍了三种线程封闭方式:栈封闭(利用方法局部变量)、ThreadLocal(线程局部变量)和Ad-hoc(程序控制)。重点分析了ThreadLocal的实现原理,包括Thread类中的ThreadLocalMap、ThreadLocal的哈希算法以及设置/获取值的机制。ThreadLocal通过为每个线程维护独立的数据副本,实现了高效的线程封闭,特别适合存储线程独有上下文数

weixin_48471044的博客 1166

从串行线程封闭到对象池、线程池

今天讲一个牛逼而实用的概念,串行线程封闭。对象池是串行线程封闭的典型应用场景;线程池糅合了对象池技术,但核心实现不依赖于对象池,很容易产生误会。 本文从串行线程封闭和对象池入手,最后通过源码分析线程池的核心原理,厘清对象池与线程池之间的误会。 线程封闭与串行线程封闭 线程封闭 线程封闭是一种常见的线程安全设计策略:仅在固定的一个线程内访问对象,不对其他线程共

数据与算法之美 963

Java并发编程学习4-线程封闭和安全发布

对象的共享 3. 线程封闭 线程封闭(Thread Confinement)是实现线程安全性的最简单方式之一。当某个对象封闭在一个线程中时,这种用法将自动实现线程安全性,即使被封闭的对象本身不是线程安全的。 在Java中使用线程封闭技术有:Swing和 JDBC 的Connection对象。 Swing的可视化组件和数据模型对象都不是线程安全的,Swing通过将它们封闭到Swing的事件分发线程中来实现线程安全性;为了进一步简化对Swing的使用,Swing还提供了invo...

wangxi06的专栏 167

线程封闭之ThreadLocal

多线程访问共享可变数据时,涉及到线程间数据同步问题。 数据都被封闭在各自的线程之中,就不需要同步,这种通过将数据封闭在线程中,而避免使同步的技术,称为线程封闭。 ThreadLocal 线程级别变量 每个线程都有一个ThreadLocal 每个线程都拥有了自己独立的一个变量 竞争条件被彻底消除了 在并发模式下是绝对安全的变量 1.示例 import java.text.SimpleDateFormat; import java.util.Random; import java.util.c

hellboy0621的博客 230

线程封闭

线程封闭 新一篇: 线程安全 &amp;lt;script&amp;gt;function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open...

南村土人 143

Java多线程-线程封闭

线程封闭:当并发访问/修改共享的数据时,通常需要使用同步来避免线程安全性问题,一种简单的方式就是使当前共享数据只能在当前线程内访问,这样就不需要同步。 实现线程封闭的方法主要有两种: 1.栈封闭:众所周知方法内的局部变量为当前线程私有,不回因为并发而出现问题,所以如果在可能的情况下尽可能使用局部变量。 2ThreadLocal封闭:ThreadLocal是Java为解决多线程提供的一种解决方

lohocc的专栏 457

栈封闭的核心原理:为什么局部变量是线程安全的?某金融交易系统的日期格式化操作在高并发下成为性能瓶颈。原本使用全局共享的SimpleDateFormat对象,即使加锁后QPS(每秒查询率)也只有2000

在多线程编程的世界中,开发人员常常陷入各种同步机制的泥潭:synchronized关键字、Lock锁、volatile变量、原子类……这些技术虽然有效,但往往伴随着性能开销和复杂性。然而,有一种被许多人忽视的技术,却能以零成本提供完美的线程安全性——这就是让我从一个真实的性能优化案例说起:某金融交易系统的日期格式化操作在高并发下成为性能瓶颈。原本使用全局共享的SimpleDateFormat对象,即使加锁后QPS(每秒查询率)也只有2000左右。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 983
上一篇: 重新认识的volatile关键字
下一篇: 守护线程
至学者
博客等级 码龄9年 180粉丝 773原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值