We know that Java has a lot of thread-safe container classes, and we know that it can be thread-safe to manage mutable state management to these thread-safe classes, but we may also encounter unthinkable problems.
For example:
Package Com.home.thread.thread8;import java.util.vector;/** * @author Gaoxu * Practice a genuine knowledge! */public class Vectorqueue {private static vectorqueue instance;private static vector<string> list;private Vectorqueue () {list = new vector<string> ();} Public vector<string> Getvector () {return list;} Public synchronized static Vectorqueue Getinstace () {if (instance==null) {instance = new Vectorqueue ();} return instance;} Public String getlast (vector<string> list) {int index = list.size () -1;return (String) list.get (index);} public void Dellast (vector<string> list) {int index = list.size () -1;list.remove (index);}}
In the above code, two methods are dealing with the vector class object, we know that vector is a safe class, then these two methods in multi-threaded access can be the right time is worth it? Let's do an example to verify that.
Let's write an example of a multithreaded call.
Package Com.home.thread.thread8;import java.util.vector;/** * @author Gaoxu Practice! */public class Vectormain {/** * @param args */public static void main (string[] args) {Vectorqueue VQ = Vectorqueue.getins Tace (); for (int i = 0; i <; i++) {string test = new String ("" + i); Vq.getvector (). Add (test);} for (int j = 0; J <; J + +) {threadtest threadtest = new ThreadTest (); Threadtest.start ();}} private static class ThreadTest extends Thread {vectorqueue VQ = vectorqueue.getinstace ();p ublic threadtest () {}public voi D run () {String data = (string) vq.getlast (Vq.getvector ()); Vq.dellast (Vq.getvector ()); SYSTEM.OUT.PRINTLN (data);}}}
Let's take a look at the results of the operation (the result is that it can be run many times, which is the problem with vectors and other thread-safe classes)
<pre class= "html" name= "code" >98765432exception in Thread "Thread-8" 1java.lang.arrayindexoutofboundsexception : Array index out of range:1 at Java.util.Vector.get (vector.java:694) at Com.home.thread.thread8.VectorQueue.getLast ( vectorqueue.java:26) at Com.home.thread.thread8.vectormain$threadtest.run (vectormain.java:40)
This is definitely not the result we want, this shows that the problem of static conditions, get and Del thread access to the list.size can be obtained by the same value, so that the same value of two threads del Operation finished the get operation has occurred as above error.
So how do we change it to get the right value? That is the way of using the client yoke, in fact, we take advantage of non-thread-safe Base object classes will be aware of the synchronization problem, then let us look at the instance.
Package Com.home.thread.thread8;import java.util.vector;/** * @author Gaoxu Practice! */public class Vectorqueue {private static vectorqueue instance;private static vector<string> list;private Vectorqueue () {list = new vector<string> ();} Public vector<string> Getvector () {return list;} Public synchronized static Vectorqueue Getinstace () {if (instance = = null) {instance = new Vectorqueue ();} return instance;} Public String getlast (vector<string> list) {synchronized (list) {int index = list.size ()-1;return (String) Lis T.get (index);}} public void Dellast (vector<string> list) {synchronized (list) {int index = list.size ()-1;list.remove (index);}}
We use the client lock, the result of the operation is as follows, we can see that the running result itself shows that the timing of the thread execution is completely unordered, but also confirms the existence of the lock.
9876543012
This way of lock, I run a lot of times, although there is no exception, but I always have a feeling that vector is not credible, haha! and a Hashtable.
Next time, let's practice, concurrenthashmap!.
The code in the instance can also be more optimized:
Package Com.home.thread.thread8;import java.util.vector;/** * @author Gaoxu Practice! */public class Vectormain {/** * @param args */public static void main (string[] args) {Vectorqueue VQ = Vectorqueue.getins Tace (); for (int i = 0; i <; i++) {string test = new String ("" + i); Vq.getvector (). Add (test);} for (int j = 0; J <; J + +) {threadtest threadtest = new ThreadTest (); Threadtest.start ();}} private static class ThreadTest extends Thread {vectorqueue VQ = vectorqueue.getinstace ();p ublic threadtest () {}public voi D run () {String data = (string) vq.getlast (); Vq.dellast (); SYSTEM.OUT.PRINTLN (data);}}}
Package Com.home.thread.thread8;import java.util.vector;/** * @author Gaoxu Practice! */public class Vectorqueue {private static vectorqueue instance;private static vector<string> list;private Vectorqueue () {list = new vector<string> ();} Public vector<string> Getvector () {return list;} Public synchronized static Vectorqueue Getinstace () {if (instance = = null) {instance = new Vectorqueue ();} return instance;} Public String GetLast () {synchronized (list) {int index = list.size ()-1;return (String) list.get (index);}} public void Dellast () {synchronized (list) {int index = list.size ()-1;list.remove (index);}}
Learning Java Multi-Threading 8-The problem of synchronizing container classes with instances