Java多线程——线程封闭
Posted Hxinguan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程——线程封闭相关的知识,希望对你有一定的参考价值。
线程封闭:当访问共享的可变数据时,通常需要同步。一种避免同步的方式就是不共享数据。如果仅在单线程内访问数据,就不需要同步,这种技术称为线程封闭(thread confinement)
线程封闭技术一个常见的应用就是JDBC的Connection对象,JDBC规范并没有要求Connection对象必须是线程安全的,在服务器应用程序中,线程从连接池获取一个Connection对象,使用完之后将对象返还给连接池。下面介绍几种线程封闭技术:
1、Ad-hoc线程封闭
Ad-hoc线程封闭是指,维护线程的封闭性的职责完全由程序实现承担,是非常脆弱的,因此在程序中尽量少使用,一般使用更强的线程封闭技术,比如栈封闭或者ThreadLocal类。
2、栈封闭
栈封闭是线程封闭的一种特列,在栈封闭中,只能通过局部变量才能访问对象。局部变量的固有属性之一就是封闭在执行栈中,其他线程无法访问这个栈,栈封闭也称为线程内部使用或者线程局部使用。简单的说就是局部变量。多个线程访问一个方法,此方法中的局部变量都会被拷贝一分儿到线程栈中。所以局部变量是不被多个线程所共享的,也就不会出现并发问题。所以能用局部变量就别用全局的变量,全局变量容易引起并发问题。
比如下面的例子:
1 public int loadTheArk(Collection<Animal> candidates) { 2 SortedSet<Animal> animals; 3 int numPairs = 0; 4 Animal candidate = null; 5 6 //animals被封装在方法中,不要使它们溢出 7 animals = new TreeSet<Animal>(new SpeciesGenderComparator()); 8 animals.addAll(candidates); 9 for(Animal a:animals){ 10 if(candidate==null || !candidate.isPotentialMate(a)){ 11 candidate = a; 12 }else{ 13 ark.load(new AnimalPair(candidate,a)); 14 ++numPairs; 15 candidate = null; 16 } 17 } 18 return numPairs; 19 }
在loadTheArk中实例化一个TreeSet对象,并将该对象的一个引用保存到animals中。此时,只有一个引用指向集合animals,这个引用被封闭到局部变量中,因此也被封闭到局部变量中。然而,如果发布了对集合animals(或者该对象中的任何内部数据)的引用,那么封闭性将被破坏,并导致对象animals的逸出。
3、ThreadLocal类
以上是关于Java多线程——线程封闭的主要内容,如果未能解决你的问题,请参考以下文章