线程封闭

1.线程封闭

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

数据库连接对应jdbc的Connection对象,Connection对象在实现的时候并没有对线程安全做太多的处理,jdbc的规范里也没有要求Connection对象必须是线程安全的。
实际在服务器应用程序中,线程从连接池获取了一个Connection对象,使用完再把Connection对象返回给连接池,由于大多数请求都是由单线程采用同步的方式来处理的,并且在Connection对象返回之前,连接池不会将它分配给其他线程。因此这种连接管理模式处理请求时隐含的将Connection对象封闭在线程里面,这样我们使用的connection对象虽然本身不是线程安全的,但是它通过线程封闭也做到了线程安全。

2.Ad-hoc 线程封闭

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

3 栈封闭

堆栈封闭其实就是方法中定义局部变量。不存在并发问题。多个线程访问一个方法的时候,方法中的局部变量都会被拷贝一份到线程的栈中(Java内存模型),所以局部变量是不会被多个线程所共享的。

栈封闭(局部变量)(复制了https://542255641.iteye.com/blog/2400917 作者:永夜-极光的博客)
栈限制是线程封闭的一种特例,只能通过局部变量才可以访问对象,局部使对象限制在执行线程中,存在于执行线程栈,其他线程无法访问这个栈,从而确保线程安全。(每一个线程都有一个工作内存,工作内存中班包括有栈,局部的基本类型变量是处于栈中,引用类型的引用处于栈中,而引用指向的对象处于堆中)。
栈限制的例子如下:
在这里插入图片描述
要理解栈封闭,需要先了解多线程之间有哪些共享的数据,有哪些不共享的数据

多线程的数据共享机制

同一进程间的线程究竟共享哪些资源呢,而又各自独享哪些资源呢?
共享的资源有

    a. 堆  由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;因此new出来的都是共享的(16位平台上分全局堆和局部堆,局部堆是独享的)
    
	b. 全局变量 它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的
	
	c. 静态变量 虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的
	
	d. 文件等公用资源  这个是共享的,使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。

独享的资源有
a. 栈 栈是独享的
b. 寄存器 这个可能会误解,因为电脑的寄存器是物理的,每个线程去取值难道不一样吗?其实线程里存放的是副本,包括程序计数器PC

因此,TreeSet对象的引用保存在annimal变量中,

annimal又是一个局部变量

局部变量保存在栈上

每个线程独享栈

因此,不同线程的栈不同,不同线程就无法操作同时操作同一个TreeSet对象,因此保证了安全性

4 ThreadLocal线程封闭

它是一个特别好的封闭方法,其实ThreadLocal内部维护了一个map,map的key是每个线程的名称,而map的value就是我们要封闭的对象。ThreadLocal提供了get、set、remove方法,每个操作都是基于当前线程的,所以它是线程安全的。
在这里插入图片描述
//ThreadLocal的get方法源码
public T get() {
Thread t = Thread.currentThread();//当前线程对象
ThreadLocalMap map = getMap(t);//get操作基于当前线程
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings(“unchecked”)
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值