Usage of synchronized in "Go" Java

Source: Internet
Author: User
Tags modifier

"Multi-threading and multi-process (1)--talking about threads and processes from the perspective of an operating system" describes in detail the threads, process relationships, and performance in the operating system, which must be understood as a basis for multithreaded learning. This article goes on to talk about an important conceptual synchronized in Java thread synchronization.

Synchronized is a key word in Java and is a synchronous lock. It modifies objects in the following ways:
1. Modify a code block, the modified code block is called the synchronous statement block, its scope is the curly braces {} In the code, the object is to call the object of this block of code;
2. Modify a method, the modified method is called the synchronous method, its scope is the whole method, the object is to call the object of this method;
3. Modify a static method whose scope of action is the entire static method, and the object of the action is all objects of this class;
4. Modify a class whose scope of action is synchronized the part enclosed in parentheses, and the object of the principal is all objects of the class.

Retouch a block of code
    1. When a thread accesses a synchronized (this) synchronization code block in an object, other threads that attempt to access the object are blocked. Let's take a look at the following example:

"Demo1": the Use of synchronized

/** * Synchronization Thread */class Syncthread implements Runnable {   private static int count;   Public Syncthread () {      count = 0;   }   Public  void Run () {      synchronized (the) {for         (int i = 0; i < 5; i++) {            try {               System.out.println (Thr Ead.currentthread (). GetName () + ":" + (count++));               Thread.Sleep (+);            } catch (Interruptedexception e) {               e.printstacktrace ();   }}}} public int GetCount () {      return count;   }}

Syncthread Call:

Syncthread syncthread = new Syncthread (); Thread thread1 = new Thread (syncthread, "SyncThread1"); Thread thread2 = new Thread (syncthread, "SyncThread2"); Thread1.start (); Thread2.start ();

The results are as follows:

syncthread1:0
Syncthread1:1
Syncthread1:2
Syncthread1:3
Syncthread1:4
Syncthread2:5
Syncthread2:6
Syncthread2:7
Syncthread2:8
syncthread2:9*

When two concurrent threads (THREAD1 and Thread2) access the synchronized code block in the same object (Syncthread), only one thread can be executed at the same time, and the other thread is blocked. You must wait for the current thread to finish executing this block of code before executing the code block. Thread1 and Thread2 are mutually exclusive, because the current object is locked when the synchronized code block is executed, and the next thread can execute and lock the object only after the code block is executed to release the lock.
Let's change the syncthread call a little bit:

Thread thread1 = new Thread (new Syncthread (), "SyncThread1"); Thread thread2 = new Thread (new Syncthread (), "SyncThread2"); Thread1.start (); Thread2.start ();

The results are as follows:

syncthread1:0
Syncthread2:1
Syncthread1:2
Syncthread2:3
Syncthread1:4
Syncthread2:5
Syncthread2:6
Syncthread1:7
Syncthread1:8
Syncthread2:9

Does it not mean that one thread executes a synchronized code block when other threads are blocked? Why the above example Thread1 and thread2 are executing at the same time. This is because synchronized only locks objects, and each object has only one lock (lock) associated with it, and the above code is equivalent to the following code:

Syncthread syncThread1 = new Syncthread (); Syncthread syncThread2 = new Syncthread (); Thread thread1 = new Thread (syncThread1, "SyncThread1"); Thread thread2 = new Thread (syncThread2, "SyncThread2"); Thread1.start (); Thread2.start ();

At this point, two Syncthread objects SyncThread1 and syncThread2 are created, and the thread Thread1 executes the SYNCTHREAD1 code (run) in the Synchronized object. The thread thread2 executes the synchronized code (run) in the SyncThread2 object, and we know that the object is locked by the synchronized, and there are two locks that lock the SyncThread1 object and the SyncThread2 object respectively. , and the two locks do not interfere with each other and do not form mutual exclusion, so two threads can execute simultaneously.

2. When one thread accesses one synchronized (this) of an object to synchronize a block of code, another thread can still access the non-synchronized (this) synchronization code block in the object.
"Demo2": Multiple threads accessing synchronized and non-synchronized code blocks

Class Counter implements runnable{private int count;   Public Counter () {count = 0;               } public void Countadd () {synchronized (this) {for (int i = 0; i < 5; i + +) {try {               System.out.println (Thread.CurrentThread (). GetName () + ":" + (count++));            Thread.Sleep (100);            } catch (Interruptedexception e) {e.printstacktrace (); }}}}//non-synchronized code block, count not read and write, so you can not synchronized public void PrintCount () {for (int i = 0; I < 5;            i + +) {try {System.out.println (Thread.CurrentThread (). GetName () + "Count:" + count);         Thread.Sleep (100);         } catch (Interruptedexception e) {e.printstacktrace ();      }}} public void Run () {String threadname = Thread.CurrentThread (). GetName ();      if (Threadname.equals ("A")) {Countadd ();      } else if (Threadname.equals ("B")) {PrintCount (); }   }} 

Calling code:

Counter Counter = new Counter (); Thread thread1 = new Thread (counter, "A"); Thread thread2 = new Thread (counter, "B"); Thread1.start (); Thread2.start ();

The results are as follows:

a:0
B count:1
A:1
B Count:2
A:2
B Count:3
A:3
B Count:4
A:4
B Count:5

The above code Countadd is a synchronized, PrintCount is non-synchronized. As you can see from the above results, when a thread accesses an object's synchronized code block, other threads can access the object's non-synchronized block of code without being blocked.

    1. Specifies that you want to lock an object

"Demo3": Specifies that a lock is to be added to an object

/** * Bank account class */class accounts {String name;   float amount;      Public account (String name, float amount) {this.name = name;   This.amount = amount;      }//Save public void deposit (float amt) {amount + = Amt;      try {thread.sleep (100);      } catch (Interruptedexception e) {e.printstacktrace ();      }}//Take money public void withdraw (float amt) {amount-= Amt;      try {thread.sleep (100);      } catch (Interruptedexception e) {e.printstacktrace ();   }} public float GetBalance () {return amount;   }}/** * Account Operation class */class Accountoperator implements runnable{private accounts;   Public Accountoperator {this.account = account;         public void Run () {synchronized (account) {account.deposit (500);         Account.withdraw (500);      System.out.println (Thread.CurrentThread (). GetName () + ":" + account.getbalance ()); }   }}

Calling code:

Account Account = new Account ("Zhang San", 10000.0f); Accountoperator accountoperator = new Accountoperator (account); final int thread_num = 5; Thread threads[] = new Thread[thread_num];for (int i = 0; i < thread_num; i + +) {   Threads[i] = new Thread (accountop Erator, "Thread" + i);   Threads[i].start ();}

The results are as follows:

thread3:10000.0
thread2:10000.0
thread1:10000.0
thread4:10000.0
thread0:10000.0

In the Run method in the Accountoperator class, we use synchronized to lock the account object. At this point, when a thread accesses the account object, other threads attempting to access the account object will block until the thread accesses the account object and ends. That means whoever gets that lock can run the code it controls.
When there is a definite object as a lock, you can write the program in a manner similar to the following.

public void method3 (Someobject obj) {   //obj locked object   synchronized (obj)   {      //Todo   }}

When there is no explicit object as a lock, just want to synchronize a piece of code, you can create a special object to act as a lock:

Class Test implements runnable{   private byte[] lock = new Byte[0];  Special instance variable public   void method ()   {      synchronized (lock) {         //Todo Synchronous code block      }   }   Public void Run () {   }}

Description: A 0-length byte array object will be more economical to create than any object-view compiled bytecode: generates a 0-length byte[] object with only 3 opcode, and object lock = new Object () requires 7 lines of opcode.

Modify a method

Synchronized modifying a method is very simple, is to add synchronized,public synchronized void method () {//todo} in front of methods; The synchronized modification method is similar to modifying a code block, except that the scope of the adornment code is the range of braces, and the scope of the adornment method is the entire function. If you change the Run method in "Demo1" to the following way, the effect is the same.

* "Demo4": Synchronized modifies a method

Public synchronized void Run () {for   (int i = 0; i < 5; i + +) {      try {         System.out.println (Thread.currentt Hread (). GetName () + ":" + (count++));         Thread.Sleep (+);      } catch (Interruptedexception e) {         e.printstacktrace ();}}   }

Synchronized acts on the whole method.
Writing one:

Public synchronized void Method () {   //Todo}

Two:

public void Method () {   synchronized (this) {      //Todo   }}

A method of writing a modifier, the second modifier is a code block, but the wording of the two is equivalent, are locked the whole method of content.

The following points should be noted when using the synchronized modification method:
1. The synchronized keyword cannot be inherited.
Although you can use synchronized to define a method, synchronized is not part of the method definition, so the Synchronized keyword cannot be inherited. If a method in the parent class uses the Synchronized keyword, and the method is overridden in a subclass, the method in the subclass is not synchronized by default, and the Synchronized keyword must be explicitly added to this method of the subclass. Of course, the corresponding method in the parent class can also be called in the subclass method, so that although the methods in the subclass are not synchronous, the subclass calls the synchronization method of the parent class, so the subclasses ' methods are equivalent to synchronizing. The example code for both of these approaches is as follows:
Add the Synchronized keyword to the subclass method

Class Parent {public   synchronized void method () {}}class Child extends the parent {public   synchronized void method ( ) { }}

Calling the parent class's synchronization method in a subclass method

Class Parent {public   synchronized void method () {   }}class child extends, parent {public   void method () {Super . method ();   
    1. You cannot use the Synchronized keyword when defining an interface method.
    2. The construction method cannot use the Synchronized keyword, but you can use the synchronized code block to synchronize.
To modify a static method

Synchronized can also modify a static method, using the following:

Public synchronized static void method () {   //Todo}

We know that a static method belongs to a class and not to an object. Similarly, the static method of synchronized modification locks all objects of this class. We have made some changes to Demo1 as follows:

"Demo5": Synchronized modified static method

/** * Synchronization Thread */class Syncthread implements Runnable {   private static int count;   Public Syncthread () {      count = 0;   }   Public synchronized static void method () {for      (int i = 0; i < 5; i + +) {         try {            System.out.println (thread.c Urrentthread (). GetName () + ":" + (count++));            Thread.Sleep (+);         } catch (Interruptedexception e) {            e.printstacktrace ();}}   }   Public synchronized void Run () {      method ();   }}

Calling code:

Syncthread syncThread1 = new Syncthread (); Syncthread syncThread2 = new Syncthread (); Thread thread1 = new Thread (syncThread1, "SyncThread1"); Thread thread2 = new Thread (syncThread2, "SyncThread2"); Thread1.start (); Thread2.start ();

The results are as follows:

syncthread1:0
Syncthread1:1
Syncthread1:2
Syncthread1:3
Syncthread1:4
Syncthread2:5
Syncthread2:6
Syncthread2:7
Syncthread2:8
Syncthread2:9

SyncThread1 and SyncThread2 are two objects of syncthread, but thread synchronization is maintained while Thread1 and thread2 are concurrently executing. This is because the static method is called in run, and the static method belongs to the class, so syncThread1 and syncThread2 are equivalent to using the same lock. This is different from the Demo1.

Modifying a class

Synchronized can also be used for a class with the following usage:

Class ClassName {public   void method () {      synchronized (classname.class) {         //Todo      }   }}

Let's make some more changes to the DEMO5.
"Demo6": Modifying a class

/** * Synchronization Thread */class Syncthread implements Runnable {   private static int count;   Public Syncthread () {      count = 0;   }   public static void Method () {      synchronized (syncthread.class) {for         (int i = 0; i < 5; i + +) {            try {               Sys Tem.out.println (Thread.CurrentThread (). GetName () + ":" + (count++));               Thread.Sleep (+);            } catch (Interruptedexception e) {               e.printstacktrace ();   }}}} Public synchronized void Run () {      method ();   }}

The effect is the same as "Demo5", when synchronized acts on a class T, it is to lock the class T and all objects of T are using the same lock.

Summarize:

A. Regardless of whether the Synchronized keyword is added to a method or an object, if the object it is acting on is non-static, the lock it obtains is an object, and if the object that the synchronized action is a static method or a class, the lock it obtains is the same lock on the class, all objects of that class.
B. Each object has only one lock (lock) associated with it, and whoever gets the lock can run the code it controls.
C. Achieving synchronization is a costly overhead, and may even result in deadlocks, so avoid unnecessary synchronization controls as much as possible.

Resources:
http://blog.csdn.net/chenguang79/article/details/677720
Http://developer.51cto.com/art/200906/132354.htm

Original: http://blog.csdn.net/luoweifu/article/details/46613015
Author: Luoweifu

Usage of synchronized in "Go" 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.