Summary of Methods (7) for thread synchronization in Java

Source: Internet
Author: User
Tags tools and utilities to domain java util

First, the synchronization method is a method of synchronized keyword modification. Because each object in Java has a built-in lock, the built-in lock protects the entire method when the method is decorated with this keyword. You need to get the built-in lock before calling the method, otherwise it will be in a blocking state. Note: The Synchronized keyword can also modify a static method, at which point the entire class is locked if the static method is called.

second, synchronous code blockThat is, a statement block that has the synchronized keyword modifier. The block of statements decorated with this keyword is automatically added with the built-in lock, which enables synchronization of code such as:
Synchronized (object) {}
Note: Synchronization is a high-overhead operation, so you should minimize the content of synchronization. It is usually not necessary to synchronize the entire method, using the synchronized code block to synchronize the key code.
    Package com.xhj.thread;     /**     * Application of thread synchronization     *      * @author Xiehejun * * */Public    class Synchronizedthread {         class Bank {            private int account = +;            public int Getaccount () {                return account;            }             /**             * Implemented with synchronous method             *              * @param money             *            /public synchronized void Save (Int. money) {Account                + = Money;            }             /** *             implemented with synchronous code blocks * * @param money */public            void save1 (int. money) {                synchronized (this) { C28/>account + = Money;}}        
Class Newthread implements Runnable {private Bank bank;            Public Newthread (Bank bank) {this.bank = Bank;                    } @Override public void Run () {for (int i = 0; i < i++) {                    BANK.SAVE1 (10);                    Bank.save (10);                SYSTEM.OUT.PRINTLN (i + "account balance:" + bank.getaccount ());  }}}/** * Create thread, call inner class */public void Usethread () {Bank Bank            = new Bank ();            Newthread new_thread = new Newthread (bank);            SYSTEM.OUT.PRINTLN ("Thread 1");            Thread thread1 = new Thread (new_thread);            Thread1.start ();            SYSTEM.OUT.PRINTLN ("Thread 2");            Thread thread2 = new Thread (new_thread);        Thread2.start ();            } public static void Main (string[] args) {Synchronizedthread st = new Synchronizedthread ();        St.usethread (); }     } 

===================================== examples and explanations of synchronization are important concepts in multi-threading. The use of synchronization ensures that in a multithreaded environment, the program does not produce error results outside of the design. There are two ways to implement synchronization, synchronous methods and synchronous blocks, both of which use the Synchronized keyword.

synchronization method: Adding a synchronized modifier to a method can make it a synchronous method, which can be a static and non-static method, but not an abstract method of an abstract class, or an interface method in an interface. The following code is an example of a synchronous method:

Public synchronized void Amethod () {     //does something} public static synchronized void Anothermethod () {     

A thread is exclusive when it executes a synchronous method. When any thread enters any of the synchronization methods of an object, all the synchronization methods of the object are locked, during which time no other thread can access any of the synchronization methods of the object until the thread executes the synchronous method it calls and exits from it. This causes it to release the object after the synchronization lock. After an object is locked by a thread, the other threads are all non-synchronous methods that can access the object.

Synchronization Block: The synchronization block synchronizes the code contained in the synchronization block by locking a specified object, while the synchronization method synchronizes the code in the method block, and in this case the locked object is the principal object itself that the synchronization method belongs to. What if this method is a static synchronization method? The thread locking is not the object of this class, nor the class itself, but the object of the Java.lang.Class type corresponding to this class. The interaction between the synchronization method and the synchronization block is limited to the same object, so the static synchronization method is restricted only by other static synchronization methods of the class to which it belongs, but not with instances (objects) of the class.

If an object has both a synchronous method and a synchronization block, then when either of the synchronization methods or the synchronization block is executed by a thread, the object is locked, the other thread cannot access the object's synchronization method at this time, and the synchronization block cannot be executed.

The synchronized keyword is used to protect shared data . Please note that "shared data", you must distinguish which data is shared data, see the following example:

public class ThreadTest implements runnable{public synchronized void run () {for (int i=0;i<10;i++) {System.out.prin  T ("" + i);  }}public static void Main (string[] args) {Runnable r1 = new ThreadTest ();//may also be written as threadtest r1 = new ThreadTest ();  Runnable r2 = new ThreadTest ();  thread T1 = new Thread (r1);  Thread t2 = new Thread (r2);  T1.start (); T2.start ();}}

In this program, run () is added with the Synchronized keyword, but it is not protected from shared data. Because the T1,T2 in this program is a thread of two objects (R1,R2). The data for different objects is different, and R1,R2 has its own run () method, so the output is unpredictable.

The purpose of synchronized is to make multiple threads of the same object, and at some point only one of the threads can access the object's synchronized data. Each object has a "lock flag", and when a thread of this object accesses one of the object's synchronized data, all the synchronized-modified data for that object is locked (because the "lock flag" is taken away by the current thread), The current thread frees the "lock flag" only if the front-end accesses the synchronized data it wants to access, so that other threads of the same object have access to the synchronized data.

Example 3:

public class ThreadTest implements runnable{public synchronized void run () {for (int i=0;i<10;i++) {System.out.print  ("" + i);  }}public static void Main (string[] args) {Runnable r = new ThreadTest ();  thread T1 = new Thread (r);  Thread t2 = new Thread (r);  T1.start (); T2.start ();}}

If you run this program 1000 times, its output must always be: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9. Because the synchronized here protect the shared data. T1,t2 is a two thread of the same object (R), and when one of the threads (for example: T1) starts executing the run () method, because run () is protected by synchronized, other threads of the same object (T2) cannot access the Synchronized method (run method). Only after T1 executes T2 will the opportunity be executed.

Example 4:

public class ThreadTest implements Runnable{public void Run () {synchronized (the) {for    (int i=0;i<10;i++) {        System.out.print ("" + i);}}    } public static void Main (string[] args) {    Runnable r = new ThreadTest ();    thread T1 = new Thread (r);    Thread t2 = new Thread (r);    T1.start ();    T2.start ();}}    

This program is the same as the result of example 3. Where possible, the scope of protection should be minimized, in the form of Example 4, this represents "this object". There is no need to protect the entire run (), the Code in Run () has only one for loop, so just protect the for loop.

Example 5:

public class ThreadTest implements Runnable{public void Run () {for (int k=0;k<5;k++) {System.out.println (Thread.curr  Entthread (). GetName () + ": For loop:" + K); }synchronized (This) {for (int k=0;k<5;k++) {System.out.println (Thread.CurrentThread (). GetName () + ": Synchronized F  or loop: "+ K");  }}}public static void Main (string[] args) {Runnable r = new ThreadTest ();  thread T1 = new Thread (R, "T1_name");  Thread t2 = new Thread (R, "T2_name");  T1.start (); T2.start ();} }

Operation Result:

T1_name:for loop:0

T1_name:for loop:1

T1_name:for Loop:2

T2_name:for loop:0

T1_name:for Loop:3

T2_name:for loop:1

T1_name:for Loop:4

T2_name:for Loop:2

T1_name:synchronized for loop:0

T2_name:for Loop:3

T1_name:synchronized for Loop:1

T2_name:for Loop:4

T1_name:synchronized for Loop:2

T1_name:synchronized for Loop:3

T1_name:synchronized for Loop:4

T2_name:synchronized for loop:0

T2_name:synchronized for Loop:1

T2_name:synchronized for Loop:2

T2_name:synchronized for Loop:3

T2_name:synchronized for Loop:4

The first for loop is not protected by a synchronized. For the first for loop, T1,T2 can be accessed at the same time. The result of the operation shows that T2 started executing when T1 was executed to k=2. T1 first executes the first for loop, at which point T2 has not finished executing the first for loop (T2 just executed to k=2). T1 starts execution of the second for loop, and when the second for loop of T1 executes to k=1, the first for loop of T2 is done. T2 wants to start the second for loop, but since T1 executes the second for loop first, the lock flag of the object is naturally in the hands of the T1 (the Synchronized method's execution also falls into the T1 hands), it will not release the lock flag when the second for loop is not executed by T1. So T2 must wait until T1 executes the second for loop before it can execute a second for loop.

=====================================

third, wait and notify

Wait (): causes a thread to be in a wait state and releases the lock of the object it holds.

Sleep (): Makes a running thread sleep, is a static method that calls this method to catch the interruptedexception exception.
Notify (): Wakes up a waiting thread, noting that when this method is called, it does not actually wake up a waiting state thread, but is determined by the JVM to wake up which thread, and not by priority.
Allnotity (): Wakes all the threads that are in the waiting state, noting that they do not give all the wake-up threads an object lock, but instead let them compete.

See more: How to use Wait, notify, Notifyall

Iv. using special domain variables (volatile) to implement thread synchronization The A.volatile keyword provides a lock-free mechanism for access to domain variables B. Using a volatile modifier domain is equivalent to telling a virtual machine that the domain might be updated by another thread. Therefore, each use of the domain is recalculated instead of making         Using the value D.volatile in the register does not provide any atomic manipulation, nor can it be used to modify the variables of the final type, for example: In the example above, you can implement thread synchronization by simply adding a volatile modifier to the account. code example:
        Just give the code to be modified, the rest of the code with the same        class Bank {            //the variable that needs to be synchronized plus the volatile            private volatile int account = +;             public int Getaccount () {                return account;            }            There is no longer a need for synchronized public             void Save (int money) {Account                + = money;            }        }
Note: The non-synchronous problem in multi-threading is mainly in the reading and writing of the domain, and if the domain itself avoids this problem, it is not necessary to modify the method of manipulating the domain. With the final domain, locked-protected and volatile domains can avoid unsynchronized problems.     V. Using a re-entry lock to implement thread synchronization a new Java.util.concurrent package is added in JavaSE5.0 to support synchronization. The Reentrantlock class is a re-entrant, mutex, and lock interface that implements the same basic behavior and semantics as using the Synchronized method, and extends its capabilities. Common methods of the Reenreantlock class are:
Note: Reentrantlock () also has a construction method that can create a fair lock, but it is not recommended to use it because it can significantly reduce the operating efficiency of the program, for example: On the basis of the above example, the rewritten code is:
       Just give the code to be modified, the rest of the code with the same        class Bank {                        private int account = +;            Need to declare this lock            private lock lock = new Reentrantlock ();            public int Getaccount () {                return account;            }            Synchronized public             void Save (int money) {                lock.lock () is no longer required here;                try{account                    + = money;                } finally{                    Lock.unlock ();                }                            }        }
Note: About the lock object and synchronized keyword selection:A. It is best to use a mechanism provided by the Java.util.concurrent package to help users handle all lock-related code.         B. If the synchronized keyword satisfies the user's needs, use synchronized because it simplifies the code C. If you need more advanced features, use the Reentrantlock class, you should pay attention to release the lock in time, otherwise there will be deadlock, usually in the finally code release lock VI, using local variables to implement thread synchronization if you use Threadlocal management variables,     Each thread that uses the variable obtains a copy of the variable, and the replicas are independent of each other so that each thread can modify its own copy of the variable without affecting other threads. Common methods of ThreadLocal class
ThreadLocal (): Creates a thread local variable get (): Returns the value in the current thread copy of this thread's local variable InitialValue (): Returns the "initial value" set (T value) of the current thread for this thread's local variable: the current thread vice of this thread local variable The value in this is set to value
For example: On the basis of the above example, the modified code is:
        Change the Bank class only, the rest of the code with the public class        bank{            //Use ThreadLocal class to manage shared variables account            private static threadlocal< integer> account = new threadlocal<integer> () {                @Override                protected Integer initialvalue () {                    return;}            ;            public void Save (int money) {                account.set (Account.get () +money);            }            public int Getaccount () {                return account.get ();            }        }
Note: Threadlocal and synchronization mechanisms are both a.threadlocal and synchronous mechanisms to solve the problem of access violation of the same variable in multi-threading. B. The former adopts a "space-for-time" approach, which uses "time-for-space" approaches Vii. using a blocking queue for thread synchronization

The previous 5 synchronization methods are synchronous at the bottom of the thread, but we should try to stay away from the underlying structure as far as possible in actual development. Using the new Java.util.concurrent package in the javaSE5.0 release will help simplify development. This section mainly uses linkedblockingqueue<e> to implement thread synchronization linkedblockingqueue<e> is an arbitrary blocking queue based on the connected node. Queues are first in, out of sequence (FIFO), about the queue will be explained in detail ~linkedblockingqueue class common Methods Linkedblockingqueue (): Create a capacity of integer.max_ The value of Linkedblockingqueue put (e): Adds an element at the end of the queue and blocks the size (): Returns the number of elements in the queue take (): Remove and return the team header element, or block code instances if the queue is empty: implementing Merchant products and traders Synchronization of Products

Note:blockingqueue<e> defines the common methods of blocking queues, especially three ways to add elements, and we should pay more attention when the queue is full:

The Add () method throws an exception

Offer () method returns false

The put () method blocks

7. Using atomic variables for thread synchronization

The root cause of the need to use thread synchronization is that operations on ordinary variables are not atomic.

So what is atomic manipulation? Atomic manipulation means reading the value of a variable, modifying the value of a variable, saving the value of a variable as a whole--these behaviors are either completed at the same time or are not completed. A tool class that creates an atomic type variable is provided in the Java util.concurrent.atomic package to simplify thread synchronization. Where the atomicinteger table can atomically update the value of int, available in an application (such as an atom-incremented counter), but cannot be used to replace an integer; Allows for unified access to tools and utilities that deal with the opportunity number class.

Common methods of the Atomicinteger class:

Atomicinteger (int initialvalue): Creates a new with the given initial value

Atomicintegeraddaddget (int dalta): atomically adds the given value to the current value

Get (): Gets the current value

code example:

Just change the bank class, the rest of the code is the same as the first example above

Class Bank {    private Atomicinteger account = new Atomicinteger (+);    Public Atomicinteger Getaccount () {        return account;     }     public void Save (int money) {        account.addandget (money);    }}

Complementary-atomic operations are mainly:  

Read and write operations for reference variables and most primitive variables (except long and double);

Read and write operations for all variables that use volatile modifiers, including long and double.

Summary of Methods (7) for thread synchronization in Java

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.