• 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

  • 相关阅读:
    List遍历时删除与迭代器(Iterator)解惑
    从一次“并发修改字段业务”引出多版本并发控制与InnoDB锁
    RocketMQ存储机制与确认重传机制
    Java中的锁
    jmeter在non-GUI模式下用法
    Java SPI机制简述
    深拷贝、浅拷贝与Cloneable接口
    Java中的小数运算与精度损失
    java中的枚举类
    SpringBoot是如何实现自动配置的
  • 原文地址:https://www.cnblogs.com/personnel/p/4583214.html
Copyright © 2020-2023  润新知