Java Concurrent Programming 3_ thread synchronization synchronized keywords

Source: Internet
Author: User
Tags visibility

In the previous blog, we explained the Java thread's memory model, see: Java Concurrent programming 2_ thread safety & memory model, and then the previous article addressed the issue of thread safety in the case of multi-threaded shared resources.

analysis of non-thread threads

public class Test implements Runnable {private int i = 0;private int GetNext () {return i++;} @Overridepublic void Run () {//Synchronizedwhile (True) {synchronized (this) {if (i<10) {System.out.println (GetNext () );} Elsebreak;}}} public static void Main (string[] args) {Test t = new Test (); thread T1 = new Thread (t); Thread t2 = new Thread (t); T1.start (); T2.start (); Thread.yield ();}}


The difference from the previous code is that the Run method is decorated with the synchronized keyword.

According to the previous blog analysis: Multithreading when accessing shared resources because the CPU in turn to each task allocated its time, and the CPU scheduling is random, so a thread is accessing the variable when the CPU has the time slice distributed to other threads, This can happen when a thread reads from the main memory to the value of a variable before it can be modified (or refreshes the main memory after modification), the other thread gains the CPU's execution and reads the value of the change from the main memory. When the CPU execution goes back to the first thread, it executes at the previous break (modify variables, etc.), and execution returns to the second thread without seeing the changed value in the first thread. This means that the visibility of thread memory is violated. Avoid the possible order in which the first output appears to appear (it may actually be a lot, because i++ is not a single atomic operation):


The i++ corresponds to the following JVM directive, so the variable may be modified by another thread during the period.

4:aload_0

5:iconst_0

6:putfield #2//Field i:i

To reflect memory visibility, the Synchronized keyword allows its protected code to be accessed serially (only by a single thread at a time). Guarantees that a thread can see the execution results of another thread in a predictable way.

Thread Synchronization

The locking mechanisms provided by Java include synchronous code blocks and synchronous methods.

Each Java object can be used as a lock to implement synchronization, which becomes a built-in lock (intrinsic lock) or monitor lock (monitor lock), a thread enters the sync belt quickly before the lock is automatically obtained, and the synchronization belt is released automatically release the lock. The displacement path to the built-in lock is to enter a synchronous code block or method protected by this lock that is not yet available to other threads.

A Java built-in lock is equivalent to a mutex (mutex), meaning that at most one thread holds the lock. when a thread A try to get a thread B when holding a lock, the thread A must wait or block, knowing that the thread B release this lock if the thread B never release the lock, then the thread A will wait forever.

Only one thread can execute a block of built-in lock protection at a time, so this lock-protected synchronization code block is executed atomically, and multiple threads do not interfere with each other as they execute the block of code.

The meaning of atomicity: a set of statements is executed as an indivisible unit. any thread that executes a synchronous block of code cannot see that another thread is executing a synchronous block of code that is protected by the same lock.

It is important not to say that the synchronized code block or the synchronized method is an indivisible whole and is atomic because there is no mutual exclusion between the different locks.

the introduction of ticket purchase example

The following is the simulation of the railway station to sell tickets, in theory, the number of tickets sold in accordance with the order of 1-10 to sell, the results with two windows (threads) to sell the result, some numbered tickets sold two times, some did not sell, and there are 0 tickets sold out. Obviously the result is wrong.

public class Test implements Runnable {private int i = 10;private void sale () {while (true) {if (i >0) {try {Thread.Sleep (10);} catch (Interruptedexception e) {e.printstacktrace ();} System.out.println (Thread.CurrentThread () + "being sold" + i + "ticket"); i--;} Elsebreak;}} @Overridepublic void Run () {sale ();} public static void Main (string[] args) {Test t = new Test (); thread T1 = new Thread (t); Thread t2 = new Thread (t); T1.start (); T2.start (); Thread.yield ();}}

This result is due to the fact that there are no simultaneous locks on resources that are shared by multiple threads. Here we are thread-synchronized to achieve the desired effect:

Synchronized code block:

Synchronized (lock) {     //synchronized code}

Lock must be a variable of a reference type.

To synchronize code blocks with synchronized:


Hey? The use of synchronous code block, how is the result or not?? Let's look at the correct sync first:

public class Test implements Runnable {private int i = 10;object o = new Object ();//commonly used:/*static*/byte[] lock = new BYT E[0];p rivate void sale () {while (true) {try {thread.sleep];} catch (Interruptedexception e) {e.printstacktrace ();} Synchronized (o) {if (I >0) {System.out.println (Thread.CurrentThread () + "is selling" + i + "ticket"); i--;} Elsebreak;}}} @Overridepublic void Run () {sale ();} public static void Main (string[] args) {Test t = new Test (); thread T1 = new Thread (t); Thread t2 = new Thread (t); T1.start (); T2.start (); Thread.yield ();}

What is the principle of thread synchronization here? Because any Java object can be a synchronous lock, the object o of the above code is a synchronous lock.

a thread executes to a synchronized code block, the thread attempts to synchronize the lock, if the synchronization lock has been locked, the thread can not get to the lock, the thread is blocked, if the synchronization lock is not locked, the thread will synchronize the lock, and hold the lock, and then execute the code block, the code block normal execution end or abnormal end, the synchronization lock will be unlocked.

So when a thread executes a synchronous code block, it holds the synchronization lock. Other threads cannot acquire a lock and cannot enter a synchronous code block (provided that the same lock is used) and can only wait for the lock to be released.

This time looking back at the synchronization code block in the previous code, because two threads use a different lock (two objects created), so even if thread A is executing a synchronous block of code, when thread 2 gets CPU execution, it checks that the lock is not locked by another thread and therefore is not mutually exclusive. The effect of thread synchronization cannot be reached.

Synchronization Method

Use synchronized as a method of a keyword-decorated class so that the method becomes a synchronous method.

The result of changing the sale function directly to the synchronized method is that although the ticket is not disorderly, only one thread is selling the ticket. So make a little bit of tweaking:

public class Test implements Runnable {private int i = 10;private void sale () {while (true) {try {Thread.Sleep (Ten)} catch (Interruptedexception e) {E.printstacktrace ();} f ();}} Private synchronized void F () {if (I >0) {System.out.println (Thread.CurrentThread () + "is selling" + i + "ticket"); i--;} Elsereturn;} @Overridepublic void Run () {sale ();} public static void Main (string[] args) {Test t = new Test (); thread T1 = new Thread (t); Thread t2 = new Thread (t); T1.start (); T2.start (); Thread.yield ();}}

Which object is the lock at this time?

When the modified method is a class method, the synchronization lock is the class object corresponding to the classes;

When the normal method is decorated, the synchronization lock is the current object, which is this.

experience: Do not misuse the Synchronized method

In peacetime programming in order to achieve the purpose of thread synchronization, in the absence of serious thinking, often occur synchronized keyword abuse, in the final analysis is not understanding the principle of synchronization of the essence.

Look at the following code:

public class Test implements runnable{         @Override public      void Run () {  f ();    }      Public synchronized void F () {          System.out.println (this);    }     public static void Main (string[] args) {          Test t1=new test ();          Test t2=new test ();  The code inside the F () cannot be synchronized for the purpose of the        new Thread (T1). Start ();          New Thread (T2). Start ();      }  } Output//[email Protected]//[email protected]

As you can see from the printed result, the function f () is not synchronized because the two threads use two synchronization locks. This tells us that it is not to be seen that a method is synchronized, and it is assumed that it is a synchronous method that is arbitrarily invoked on different threads.


Note: The above code is used several times in the Thread.Sleep (long) method, is to let the current thread sleep for a while, this method will let the current thread to abandon the CPU execution, in the time waiting state, the CPU is not allocated for it. Because different machines may not be prone to the thread transitions that we expect, the goal of this is to force the thread to switch.

In addition, using sleep in the synchronized code is not valid. Because the thread sleeps after the CPU does not allocate time slices for it, but this time the thread has got a sync lock, even if the long-dead, it will not be the synchronization lock out, other threads get CPU execution but suffer from no synchronization lock and be rejected. This is the state of the learning thread behind it.


Writing code doesn't have to be understood, and understanding does not necessarily make it clear to others. It's not easy to make a clear statement about a thing in words.

Java Concurrent Programming 3_ thread synchronization synchronized keywords

Related Article

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.