Vector 是线程安全的,是不是在多线程下操作Vector就可以不用加Synchronized

如标题一样,如果之前让我回答,我会说,是的,在多线程的环境下操作Vector,不需要加Synchronized。

但是我今天无意间看到一篇文章,我才发现我之前的想法是错误的,这篇文章的地址:

http://zhangbq168.blog.163.com/blog/static/2373530520082332459511/

我摘抄关键的一部分:

Vector 比 ArrayList慢,是因为vector本身是同步的,而arraylist不是
所以,没有涉及到同步的推荐用arraylist.

看jdk关于vector说明的第3段:
As of the Java 2 platform v1.2, this class has been retrofitted to implement List, so that it becomes a part of Java‘s collection framework. Unlike the new collection implementations, Vector is synchronized.

显然,vector是同步的,楼主如不想自己实现同步的话,还是将就用一下vector
既然大家都讲到了同步,那么也稍微谈一下,同步了的Hashtable和Vector真的那么有用吗?真的如果用了socalled thread-safe Hashtable and Vector程序代码就不用再同步了吗?
这个例子(Vector vec; Object element;)
if (!vec.contains(element))
   vec.add(element);
这段代码可以不同步吗?不可以,context switch might take place right after you do the containg check.
所以,在程序中还是需要:
synchronized (vec)
{
  if (!vec.contains(element))
   vec.add(element);
}
这样Synchronized Vector比起没有Synchronized ArrayList和LinkedList来说一点好处都没有了。

当时我看到这段内容时,我才发现,是的,先判断当前Vector是否存在这个元素,如果没有,就添加。

我看了一下Vector.java 源代码,发现 contains方法是非同步的。

我自已也写了一个测试程序,结果证明在程序中还是需要:
synchronized (vec)
{
  if (!vec.contains(element))
   vec.add(element);
}

---------------------------------------------------------------------------------------------------------------------

我写的测试代码如下:

/*
 * 测试Vector在多线程下进行任何操作是否真的不需要加 Synchronized
 */
package test.thread;

import java.util.Vector;

public class TestVector2
{
 Vector<Integer> data;
 
 public TestVector2()
 {
  data = new Vector<Integer>();
  
  for(int i=0;i<10;i++)
  {
   new Add().start();
  }
  
  new Del().start();
 }
 
 //在多线程进行添加
 class Add extends Thread
 {
  public void run()
  {
   for(int i=0;i<100;i++)
   {
    //synchronized(data){
       if(!data.contains(6))
       {
        data.add(6);
        
        int size = data.size();
        
        if(size > 1)
        {
         System.out.println("data.size > 1  = " + size);
         
         for(int v : data)
         {
          System.err.println(v);
         }
//        }

}
       }
       
       
       try
    {
     sleep((int)(Math.random() * 30));
    }
    catch (InterruptedException e)
    {
     e.printStackTrace();
    }  
   }
  }
 }
 
 //删除
 class Del extends Thread
 {
  public void run()
  {
   for(int i=0;i<100;i++)
   {
       if(data.contains(6))
       {
        data.removeElement(6);
       }
       
       try
    {
     sleep((int)(Math.random() * 30));
    }
    catch (InterruptedException e)
    {
     e.printStackTrace();
    }  
   }
  }
 }
 
 public static void main(String[] args)
 {
  new TestVector2();
 }

}

结果截屏:

2012-02-28

时间: 2024-10-06 07:38:42

Vector 是线程安全的,是不是在多线程下操作Vector就可以不用加Synchronized的相关文章

(转)多线程下:Vector、Hashtable、ArrayList、LinkedList、HashMap 性能特征

最近在研究关于多线程环境下如何提升性能,在程序中执行最多的是“查询”,但同时也要维护数据的“添加”和“删除” 目前在 Hashtable 和 HashMap 中选择. 看了jdk文档,我们知道 Hashtable是同步的,而HashMap是不同步的. 所以一开始的时候,我采用的是 Hashtable,因为程序中80%的时间是在进行“查询”,所以为了提升速度,我改为 HashMap,经过几个小时的上线测试发现一个问题: 因为我在另一个单独的线程中每隔30秒对HashMap进行数据的维护(删除数据)

多线程下操作数字要用类System.Threading.Interlocked

public class ServiceStatistics { private int _sourseCount = 0; /// <summary> /// 处理源数据量 /// </summary> public int SourseCount { get { return _sourseCount; } } private int _destinationCount = 0; /// <summary> /// 返回结果数据量 /// </summary&

对于多线程下Servlet以及Session的一些理解

今天,小伙伴突然问到了Servlet是不是线程安全的问题.脑子当时一卡壳,只想到了单实例多线程.这里做一些总结. Servlet体系是建立在Java多线程的基础之上的,它的生命周期是由Tomcat来维护的.当客户端第一次请求Servlet的时候,tomcat会根据web.xml配置文件实例化servlet,当又有一个客户端访问该servlet的时候,不会再实例化该servlet,也就是多个线程在使用这个实例. Servlet线程池 serlvet采用多线程来处理多个请求同时访问,Tomcat容器

多线程下C#如何保证线程安全?

多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题.所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的. 线程安全问题都是由全局变量及静态变量引起的. 为了保证多线程情况下,访问静态变量的安全,可以用锁机制来保证,如下所示: 1 //需要加锁的静态全局变量 2 private static bool _isOK = false; 3 //lock只能锁定一

JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序员杜鹏程的博客:http://blog.csdn.net/m366917 我们来继续学习多线程 Lock锁的使用 虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock Lock void lock():获取锁 v

多线程下的进程同步(线程同步问题总结篇)

之前写过两篇关于线程同步问题的文章(一,二),这篇中将对相关话题进行总结,本文中也对.NET 4.0中新增的一些同步机制进行了介绍. 首先需要说明的是为什么需要线程功能同步.MSDN中有这样一段话很好的解释了这个问题: 当多个线程可以调用单个对象的属性和方法时,对这些调用进行同步处理是非常重要的.否则,一个线程可能会中断另一个线程正在执行的任务,使该对象处于一种无效状态. 也就说在默认无同步的情况下,任何线程都可以随时访问任何方法或字段,但一次只能有一个线程访问这些对象.另外,MSDN中也给出定

c++11 线程:让你的多线程任务更轻松

英文原文:C++ 11 Threading: Make your (multitasking) life easier 转载:http://www.oschina.net/translate/cplusplus-11-threading-make-your-multitasking-life 介绍 本文旨在帮助有经验的Win32程序员来了解c++ 11线程库及同步对象 和 Win32线程及同步对象之间的区别和相似之处. 在Win32中,所有的同步对象句柄(HANDLE)是全局句柄.它们可以被共享

使用线程局部存储实现多线程下的日志系统(转)

http://www.ibm.com/developerworks/cn/linux/1310_qianbh_threadlog/index.html 多线程编程向来不容易,在多线程环境下实现日志系统是很多程序员亟须解决的问题.在本文中详细介绍了线程局部存储的概念.原理,并用代码示例详细展示了如何使用线程局部存储来实现多线程下的日志系统. 概述 通常来说,在应用程序中需要日志来记录程序运行的状态,以便后期问题的跟踪定位.在日志系统的设计中,通常会有一个总的日志系统来统一协调这些日志的设置如位置.

线程------竞争,互斥量---多线程对同一文件读写问题

当多个控制线程共享相同的内存时呢,需要确保每个线程看到一致的数据视图. 如果每个线程使用的变量都是其他线程不会读取和修改,那么就不存在一致性的问题. 线程互斥接口用来保护数据,用于确保同一时间只有一个线程访问数据. 互斥:限制代码---独占 很久以前: 下面程序存在竞争问题的哟,当创建20个线程,每个线程都对同一个文件进行读写操作,有可能发生N个线程同时对文件进行打开和读操作,在写的过程可能会对同一个数重复进行+1操作.比如说读到  1, 然后N个线程取到1 并对1这个数做+1操作. /* 实现