不太明白Vector线程安全指是的什么,源代码中Vector的成员方法都加了synchronized,可是这样也有可能出问题啊?Vector<String> test = Vector<String>();
.......
.......
for (i = 0; i < test.size(); i++)
{
/////////////////在此处当前线程时间片到期

///线程重新获取时间片,但test内元素有可能已经被其他线程修改
System.out.println(test.get(i));
}

解决方案 »

  1.   

    Vector的所有操作方法都被同步了,既然被同步了,多个线程就不可能同时访问vector中的数据,只能一个一个地访问,所以不会出现数据混乱的情况,所以是线程安全的。如果不同步的话,对于同一个vector实例,如果第一个线程添加一个数据进去,第二个线程删除一个数据,你说最终结果是vector中有多少个数据?不能确定吧!这就是不同步的结果,所以在多线程下不能保证数据按照你的意思进行处理,也就是线程不安全的。 
      

  2.   

    楼主这个问题提的很好。我一直认为java.util里那些所谓线程安全的集合对象都是垃圾。基于单个方法的同步在实际应用中基本上不起什么作用,其负面作用是很多人以为直接用这些对象就能保证线程安全。想楼主的代码中提到的场景经常出现,要保证线程安全就必需自己用synchronized把整个代码片段包起来。
    synchronized(test)
    {
    ...
    }类似的我们经常用到的场景比如: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实现。
      

  3.   

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

  4.   

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

  5.   

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

  6.   

    回楼上,
    反正我是从来不用那些所谓线程安全的集合类的。要同步自己加synchronized,
    你说的没错,通常单个方法的同步是不能满足实际需要的。