• Vector、HashTable线程不安全示例


    下面这样写法是Vector线程不安全的写法:

    import java.util.Vector;
     
    public class Test { 
         private static Vector<Integer> vector = new Vector<Integer>();
     
            public static void main(String[] args) {
                while (true) {
                    for (int i = 0; i < 10; i++) {
                        System.out.println("添加");
                        vector.add(i);
                    }
     
                    Thread removeThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for (int i = 0; i < vector.size(); i++) {
                                System.out.println("removeThread删除");
                                vector.remove(i);
                            }
                        }
                    });
     
                    Thread printThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for (int i = 0; i < vector.size(); i++) {
                                System.out.println("printThread获取");
     
                                System.out.println((vector.get(i)));
                            }
                        }
                    });
     
                    removeThread.start();
                    printThread.start();
     
                    //不要同时产生过多的线程,否则会导致操作系统假死
                   while (Thread.activeCount() > 20);
                }
            }
      } }

      尽管Vector get()、remove()、get() 方法是I同步的 但运行上面程序会出现以下错误:

    java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0
        at java.util.Vector.get(Vector.java:744)
        at Test$2.run(Test.java:29)
        at java.lang.Thread.run(Thread.java:722)
    Exception in thread "Thread-14857" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0
        at java.util.Vector.get(Vector.java:744)
        at Test$2.run(Test.java:29)

    HashTable线程不安全写法:

    import java.util.Hashtable;
    import java.util.Map;
     
    public class HashmapTest {
        
         private  static Map<Integer,Integer> hashtable= new Hashtable<Integer,Integer>();
          public static void main(String[] args) {
           while(true){
               for (int i = 0; i < 10; i++) {
                       System.out.println("添加");
                     hashtable.put(i, i);
               }
               Thread removeThread = new Thread(new Runnable() {
                @Override
                public void run() {
                 Iterator it = hashtable.entrySet().iterator();
                      while (it.hasNext()) {
                      Map.Entry<integer integer=""> entry=(Entry<integer integer="">) it.next();  
                               System.out.println("delete this: "+entry.getKey()+"==="+entry.getValue());  
                                it.remove(); 
                    } 
                        }
                         
               
               Thread  getThread = new Thread(new Runnable() {
                @Override
                public void run() {
                     for (int i = 0; i < hashtable.size(); i++) {
                         System.out.println("getThread获取");
                         System.out.println((hashtable.get(i)));
                     }            
                }
            });
               removeThread.start();
               getThread.start();
              while (Thread.activeCount() > 20);
             }
          }
    }

      会出现很多null值,但不错,因为没有那个key ,但不会报错

    getThread获取
    null
    getThread获取
    null

      在多线程环境中,如果不在方法调用端做额外的同步措施,使用这段仍是线程不安全的,因为如果一个线程恰好再错误的时间删除了一个元素, 导致i不在可用的话,get方法会抛出一个ArrayIndexOutOfBoundsException

    import java.util.Vector;
     
    public class Test { 
         private static Vector<Integer> vector = new Vector<Integer>();
     
            public static void main(String[] args) {
                while (true) {
                    for (int i = 0; i < 10; i++) {
                        System.out.println("添加");
                        vector.add(i);
                    }
     
                    Thread removeThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            synchronized (vector) {
                                  for (int i = 0; i < vector.size(); i++) {
                                      System.out.println("removeThread删除");
                                      vector.remove(i);
                                  }
                            }
                        }
                    });
     
                    Thread printThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            synchronized (vector) {
                            for (int i = 0; i < vector.size(); i++) {
                                System.out.println("printThread获取");
     
                                System.out.println((vector.get(i)));
                            }
                            }
                        }
                    });
     
                    removeThread.start();
                    printThread.start();
     
                    //不要同时产生过多的线程,否则会导致操作系统假死
                   while (Thread.activeCount() > 20);
                }
          }
     }
  • 相关阅读:
    ZT 二叉树先序,中序,后序遍历非递归实现
    二叉树的遍历(一)
    Z :彻底了解指针数组,数组指针以及函数指针 [复
    ZT 复杂的函数指针例子分析 2008
    D:hunting2014小题目字符串倒序
    本周实验的PSP0过程文档
    构建之法阅读笔记02
    第二周学习进度
    实现自动生成30道四则运算题目(2)
    实现自动生成30道四则运算题目
  • 原文地址:https://www.cnblogs.com/jing99/p/11306496.html
Copyright © 2020-2023  润新知