Vector是线程安全的

上次被问到,vector是线程安全的,一直不知道是为什么,看了csdn上一篇提问(http://bbs.csdn.net/topics/320059353),简要总结一下:


Vector test = Vector();
.......
.......
for  (i =  0 ; i < test.size(); i++)
{
     /////////////////在此处当前线程时间片到期
     
     ///线程重新获取时间片,但test内元素有可能已经被其他线程修改
     System.out.println(test.get(i));
}

1.Vector中的方法是同步的。Vector的所有操作方法都被同步了,既然被同步了,多个线程就不可能同时访问vector中的数据,只能一个一个地访问,所以不会出现数据混乱的情况,所以是线程安全的。


2.同一个vector,A线程访问的时候,B线程不能访问而挂起(等待状态),等A释放对vector的锁以后B才能访问。而同一个List可以被多个线程同时访问 。

3.Vector所谓的线程安全是指调用Vector类的成员方法时,其他线程不能再访问该Vector对象。但是在调用两个Vector成员方法时,当前线程有可能再完成第一个方法后时间片到期,这时其他线程可以访问该Vector对象,造成调用第二个成员方法的结果可能与预想结果不同。这时为保证线程安全,需要加synchronized。

问题引导到SB的线程安全问题:
A.
synchronized (map){
Object value = map.get(key);
if (value ==  null )
{
     value =  new  Object();
     map.put(key,value);
}
return  value;}

上面代码中 map 即使是线程安全的也没有用,如果不在外面加synchronized,map.get和map.put之间的代码片段都有可能被其他线程重入,可能出现同一个key对应多个value.

另一方面,其他情况下可能不需要线程同步,这时候所谓线程安全就是多余了。StringBuffer就是个典型的例子,我还从来没见过有人把StringBuffer用在多线程中。显然SUN也认识到了这点,重写了一个功能相同的但不支持线程安全的StringBuilder,后期的编译器中把String相加的代码都用StringBuilder实现。

B.当两个线程同时执行sb.append()操作时,StringBuffer可以保证2个操作都被执行,不会其中一个被另一个冲掉,因为append()方法是synchronized的,这样2个append是先后执行的。但是StringBuilder则有可能发生其中一个操作被另一个冲掉的情况,因为2个线程的append()方法不需要获得锁。我觉得,所谓的线程安全,大概也就只能做到这点了,保证StringBuffer里面的方法本身不会因为同步执行而发生错误的结果。但是由于我们的应用中,如果需要控制同步,肯定不止在这个层次,否则,一般都是不需要同步的(局部变量),因此才诞生了StringBuilder方法。


vector线程安全的原因已知,但如何应用同步,同时其余的线程安全原因,也需要抽时间归纳一下

你可能感兴趣的:(J2EE)