In java, the time slice allocated by the cpu to each thread is random, and many of java's threads share one resource. For example, train tickets are certain when train tickets are sold, however, the window for selling train tickets is everywhere, and each window is equivalent to a thread. So many threads share all the train ticket resources. If two threads use this resource at the same time point, the train tickets they take out are the same (with the same seat number), which will cause passengers trouble. For example, the following program:
Package com. pakage. threadAndRunnable; public class Runnable_demo implements Runnable {private int ticket = 10; public Runnable_demo () {}@ Override public void run () {for (int I = 0; I <20; I ++) {if (this. ticket> 0) {// sleep for 1 s, in order to make the effect more obvious, otherwise it may not work try {Thread. sleep (1000);} catch (Exception e) {e. printStackTrace ();} System. out. println (Thread. currentThread (). getName () + "number window sale:" + this. ticket -- + "ticket") ;}} public static void main (String args []) {Runnable_demo demo = new Runnable_demo (); // create three new threads (demo, "a") based on the train ticket "). start (); new Thread (demo, "B "). start (); new Thread (demo, "c "). start ();}}
We can see that both Window c and window B have sold tickets no. 10, and window a and window B have sold tickets No. 0 and-1 respectively. The reason for this is: 1. When the c thread and the B thread are at ticket = 10, after the c thread obtains the No. 10 ticket, ticket hasn't come yet and is reduced by 1, thread B retrieves ticket. At this time, ticket is equal to 10. 2. When ticket is equal to 1, the c thread obtains the No. 1 ticket, and ticket does not come yet and minus 1, line a and line B have successively entered the if judgment statement. Then ticket is reduced by 1, so when line a and line B get the votes, they get the votes 0 and-1. How can we change the above situation? We can do this: when a thread wants to use the train ticket resource, we will give it a lock, wait until it locks the task to another thread that uses the resource. In this way, the above situation will not occur. The keyword synchronized is used to implement the lock. The synchronized keyword can be used in two ways: 1. the synchronous method is formed before the method name; 2. the synchronous block is formed before the block. 1. Use the synchronization method to show the preceding example as follows:
Package com. pakage. threadAndRunnable; public class Runnable_demo implements Runnable {private int ticket = 10; public Runnable_demo () {}@ Override public void run () {for (int I = 0; I <20; I ++) {if (this. ticket> 0) {// sleep for 1 s, in order to make the effect more obvious, otherwise it may not work try {Thread. sleep (1000);} catch (Exception e) {e. printStackTrace ();} this. sale () ;}} public synchronized void sale () {if (this. ticket> 0) {System. out. println (Thread. currentThread (). getName () + "number window sale:" + this. ticket -- + "ticket") ;}} public static void main (String args []) {Runnable_demo demo = new Runnable_demo (); // create three new threads (demo, "a") based on the train ticket "). start (); new Thread (demo, "B "). start (); new Thread (demo, "c "). start ();}}
2. Use the synchronization block to modify the preceding example:
Package com. pakage. threadAndRunnable; public class Runnable_demo implements Runnable {private int ticket = 10; public Runnable_demo () {}@ Override public void run () {for (int I = 0; I <20; I ++) {<span style = "color: # ff0000"> synchronized </span> (this) {if (this. ticket> 0) {// sleep for 1 s, in order to make the effect more obvious, otherwise it may not work try {Thread. sleep (1000);} catch (Exception e) {e. printStackTrace ();} System. out. println (Thread. currentThread (). getName () + "number window sale:" + this. ticket -- + "ticket") ;}}} public static void main (String args []) {Runnable_demo demo = new Runnable_demo (); // create three new threads (demo, "a") based on the train ticket "). start (); new Thread (demo, "B "). start (); new Thread (demo, "c "). start ();}}