What is the difference between ArrayList and vectors? What's the difference between HashMap and Hashtable? What's the difference between StringBuilder and StringBuffer? These are the basic questions that are common in the Java interview. In the face of this problem, the answer is: ArrayList is non-thread-safe, vector is thread-safe, HashMap is non-thread-safe, Hashtable is thread-safe, StringBuilder is non-thread-safe, StringBuffer is thread-safe. Because this is last night on the back of the "Java Plane Test book" above. At this point, if you continue to ask: what is thread safety? What is the difference between thread-safe and non-threading security? Under what circumstances are they used? Such a series of problems, a mouthful of old blood is sprayed out ...
Non-thread-safe phenomenon simulation
This is illustrated by using both ArrayList and vectors.
The following code, in the main thread, new a non-thread-safe ArrayList, and then open 1000 threads to add elements to this ArrayList, each thread to add 100 elements, and so on when all the threads execute, the size of this ArrayList should be how much? It's supposed to be 100,000?
Public classmain{ Public Static voidMain (string[] args) {//Test 10 times for(inti = 0; I < 10; i++) {test (); } } Public Static voidTest () {//list to test withlist<object> list =NewArraylist<object>(); //Number of threads (+) intThreadCount = 1000; //to allow the main thread to wait for the ThreadCount child thread to finish executingCountdownlatch Countdownlatch =NewCountdownlatch (ThreadCount); //start ThreadCount Child threads for(inti = 0; i < ThreadCount; i++) {thread thread=NewThread (NewMyThread (list, countdownlatch)); Thread.Start (); } Try { //The main thread waits for all child threads to complete before executing downcountdownlatch.await (); } Catch(interruptedexception e) {e.printstacktrace (); } //Size of ListSystem.out.println (List.size ()); }} classMyThreadImplementsrunnable{PrivateList<object>list; PrivateCountdownlatch Countdownlatch; PublicMyThread (list<object>list, Countdownlatch countdownlatch) { This. List =list; This. Countdownlatch =Countdownlatch; } Public voidrun () {//each thread adds 100 elements to a list for(inti = 0; I < 100; i++) {List.add (NewObject ()); } //complete a child threadCountdownlatch.countdown (); }}
There were 10 tests on it (why Test 10 times?). Because non-threading security does not always cause problems).
Output Result:
99946
100000
100000
100000
99998
99959
100000
99975
100000
99996
The above output found that not every test results are 100000, several times the final ArrayList size is less than 100000, even occasionally throws a indexoutofboundsexception exception. (If you don't have this phenomenon you can try it a few more times)
This is the problem with non-threading security. If the above code is used in a production environment, there will be a bug.
And then using a thread-safe vector to test it, the above code changes one place, in the test () method
List<Object> list =
new
ArrayList<Object>();
Change into
List<Object> list =
new
Vector<Object>();
Output Result: run the program again.
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
Run a few more times and find it all 100000, without any problems. Because vectors are thread-safe, there is no problem when working with the same vector object in multithreaded operation.
If you try again with LinkedList, there will also be ArrayList similar problems, because LinkedList is also non-thread safe.
How to choose between them
Non-thread-safe refers to a problem that can occur with multithreaded operations on the same object. Thread safety is not a problem with multithreaded operations on the same object.
Thread safety must use many synchronized keywords to synchronize control, so it inevitably leads to degraded performance.
So when using, if multiple threads are working on the same object, use a thread-safe vector, or use a more efficient ArrayList.
Non-thread safe! = is not secure
Someone in the process of using an incorrect point of view: My program is multi-threaded, can not use ArrayList to use the vector, so it is safe.
Non-thread-safe is not available in multithreaded environments. Notice what I've said above: multithreading operates on the same object. Note that it is the same object. The top one, for example, is a ArrayList of new in the main thread, and then multiple threads manipulate the same ArrayList object.
If it is a new ArrayList in each thread, and this ArrayList is only used in this thread, then it is certainly not a problem.
Thread-Safe implementation
Thread safety is implemented through thread synchronization control, which is the Synchronized keyword.
Here, I use code to implement a non-thread-safe counter and thread-safe counter counter, respectively, and they are multithreaded test.
Non-thread-safe counters:
Public classmain{ Public Static voidMain (string[] args) {//Test 10 times for(inti = 0; I < 10; i++) {test (); } } Public Static voidTest () {//counterCounter Counter =NewCounter (); //Number of threads (+) intThreadCount = 1000; //to allow the main thread to wait for the ThreadCount child thread to finish executingCountdownlatch Countdownlatch =NewCountdownlatch (ThreadCount); //start ThreadCount Child threads for(inti = 0; i < ThreadCount; i++) {thread thread=NewThread (NewMyThread (counter, countdownlatch)); Thread.Start (); } Try { //The main thread waits for all child threads to complete before executing downcountdownlatch.await (); } Catch(interruptedexception e) {e.printstacktrace (); } //value of the counterSystem.out.println (Counter.getcount ()); }} classMyThreadImplementsrunnable{PrivateCounter Counter; PrivateCountdownlatch Countdownlatch; PublicMyThread (Counter Counter, Countdownlatch countdownlatch) { This. Counter =counter; This. Countdownlatch =Countdownlatch; } Public voidrun () {//Each thread accumulates 10,000 times into the counter for(inti = 0; I < 10000; i++) {counter.addcount (); } //complete a child threadCountdownlatch.countdown (); }} classcounter{Private intCount = 0; Public intGetCount () {returncount; } Public voidAddcount () {count++; }}
In the test code of the polygon, open 1000 threads, each thread increments the counter 10,000 times, and the final output should be 10000000.
However, the counter in the above code is not synchronized, so it is not thread-safe.
Output Result:
9963727
9973178
9999577
9987650
9988734
9988665
9987820
9990847
9992305
9972233
Change the counter to a thread-safe counter with a slight modification:
class counter{ privateint count = 0; Public int GetCount () { return count; } Public synchronized void Addcount () { count+ +; }}
The above just adds the synchronized synchronization control to the Addcount () method and becomes a thread-safe counter. Execute the program again.
Output Result:
10000000
10000000
10000000
10000000
10000000
10000000
10000000
10000000
10000000
10000000
Thread-safe and non-thread-safe