Vectors, HashTable, HashMap and Concurrenthashmap

Source: Internet
Author: User

Java concurrent programming, Chapter 2.1. What is thread safety when talking about thread safety, an example is given to consider the following code fragment, which iterates over the elements in a vector. Although all vector methods are synchronous, it is still unsafe to use this code without additional synchronization in a multithreaded environment, because if another line
When a process deletes an element in the wrong time, get () throws a arrayindexoutofboundsexception.
Vector v = new vector ();
Contains race conditions--may require external synchronization
for (int i=0; i<v.size (); i++) {
DoSomething (V.get (i));
}
What happens here is that there is a precondition in the Get index specification that index must be non-negative and less than size (). However, in a multithreaded environment, there is no way to know if the last checked size () value is still valid, so i<size () cannot be determined unless the vector is locked exclusively after the last call to size ().

So write code experiment, (start mainly want to try, but found not to try out. The principle to see the API are understood, but later is and this test method seriously. )

 PackageCom.lan;ImportJava.util.Vector;Importjava.util.concurrent.BrokenBarrierException;ImportJava.util.concurrent.CyclicBarrier;ImportJava.util.concurrent.ExecutorService;Importjava.util.concurrent.Executors;ImportLombok. Allargsconstructor; Public classRunn {StaticExecutorservice exec = executors.newfixedthreadpool (1000); StaticCyclicbarrier barrier =NewCyclicbarrier (3);  Public Static voidMain (string[] args) {Try{             for(intk = 0; K < 500; k++) {Vector v=NewVector<integer>();  for(inti = 0; I < 2; i++) {v.add (i); }//System.out.println ("Main size" +v.size ());                 for(inti = 0; I < v.size (); i++) {v.get (i);//System.out.println (i+ "Main."    +v.get (i));                 }                //if (k==20)//V.remove (a);Exec.submit (NewRead (v,barrier)); Exec.submit (NewDelete (v,barrier)); Try{barrier.await ();//Thread.Sleep (+);}Catch(Exception e) {e.printstacktrace (); } System.out.println ("--------Times:" +k+ "-------------"); } thread.sleep (1000);        Exec.shutdown (); }Catch(Exception e) {e.printstacktrace (); System.exit (0); } }} @AllArgsConstructorclassReadImplementsrunnable{PrivateVector v; Privatecyclicbarrier Barrier;  Public voidrun () {Try {             for(inti = 0; I < v.size (); i++) {v.get (i);//System.out.println (i+ "read-" +v.get (i));            }        } Catch(Exception e) {e.printstacktrace (); }finally{            Try{barrier.await (); } Catch(Exception e) {e.printstacktrace (); } }} @AllArgsConstructorclassDeleteImplementsrunnable{PrivateVector v; Privatecyclicbarrier Barrier;  Public voidrun () {Try{v.remove (1);//System.out.println ("Delete:" +v.remove (V.size ()-1));}Catch(Exception e) {e.printstacktrace (); }finally{            Try{barrier.await (); } Catch(Exception e) {e.printstacktrace (); System.out.println ("Delete Error"); }        }    }}

But has been not measured out, may be not many times there is a relationship, and then finally I get the same results as below. So the intention of the program is improved, so that the non-atomicity is more obvious.

 PackageCom.lan;ImportJava.util.Vector;ImportJava.util.concurrent.ExecutorService;Importjava.util.concurrent.Executors;ImportLombok. Allargsconstructor; Public classRunn {StaticExecutorservice exec = executors.newfixedthreadpool (1000);  Public Static voidMain (string[] args)throwsException {Vector v=NewVector<integer>();  for(inti = 0; I < 5; i++) {v.add (i); } System.out.println ("Main size" +v.size ());  for(inti = 0; I < v.size (); i++) {System.out.println (i+ "Main." +V.get (i)); } exec.submit (NewRead (v)); Exec.submit (NewDelete (v)); }} @AllArgsConstructorclassReadImplementsrunnable{PrivateVector v;  Public voidrun () {Try{System.out.println ("Read Size" +v.size ());  for(inti = 0; I < v.size (); i++) {System.out.println ("I:" +i); }             for(inti = 0; I < v.size (); i++) {                if(i==4) {Thread.Sleep (500); } System.out.println (I+ "read-" +V.get (i)); }        } Catch(Exception e) {e.printstacktrace (); } }} @AllArgsConstructorclassDeleteImplementsrunnable{PrivateVector v;  Public voidrun () {Try{Thread.Sleep (450); System.out.println ("Delete:" +v.remove (4)); } Catch(interruptedexception e) {e.printstacktrace (); }    }}
The results are as follows:
Main Size50 main.01 main.12 main.23 main.34 main.4Read Size5I:0I:1I:2I:3I:40read-01read-12read-23read-3Delete:4Java.lang.ArrayIndexOutOfBoundsException:Array index out of range:4At java.util.Vector.get (Vector.java:744) at Com.lan.read.run (Runn.java:42) at Java.util.concurrent.executors$runnableadapter.call (Executors.java:471) at Java.util.concurrent.FutureTask.run (Futuretask.java:262) at Java.util.concurrent.ThreadPoolExecutor.runWorker (Threadpoolexecutor.java:1145) at Java.util.concurrent.threadpoolexecutor$worker.run (Threadpoolexecutor.java:615) at Java.lang.Thread.run (Thread.java:744)

Obviously, vector is thread-safe, why is there such a problem here? CTRL + Left click, view source code, found that almost all methods of vector class are synchronized decorated, but notice a detail

     Public synchronized E get (int  index) {        if (index >= elementcount)            throw  New  arrayindexoutofboundsexception (index);         return Elementdata (index);    }

The elementdata can be manipulated by other threads before and after the If judgment, and this method is locked, not the vector object. So, like vectors and Hashtable, it's strictly a thread-insecure class. However, in the case of a small amount of concurrency, this insecurity is very difficult to appear. (This can be found in many different ways from the previous test)

HashMap is much simpler, just guarantee the correct behavior of single-threaded, it is not thread-safe itself, but because there is no synchronized internal lock, do not need to hold and release the lock, so its performance is superior to the vector and Hashtable.

Cond...

Vectors, HashTable, HashMap and Concurrenthashmap

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.