An example of synchronized modification method in Java multithreaded program _java

Source: Internet
Author: User
Tags sleep

Before Java 5, the use of the Synchronized keyword to implement the lock function.

The Synchronized keyword can be used as a modifier for a method (a synchronization method) or as a statement within a function (a synchronized code block).

Master synchronized, the key is to grasp the thing as a lock. For a non-static method of a Class (member method), it means to get the lock on an object instance, for the static method (class method) of the class, to get the lock of the class object of the classes, and for the synchronized code block, to specify which object's lock is acquired. Synchronous non-static methods can be treated as synchronized (this) {...} containing the entire method. code block.

Whether it's a synchronized code block or a sync method, only one thread can enter at a time (at the same time, at most one thread executes the segment of code.) , if other threads attempt to enter (whether the same synchronized block or a different synchronized block), the JVM hangs them (into the lock pool). This structure is called the Critical Region (critical section) in the Concurrency theory.

Within the JVM, for efficiency, each thread running at the same time has a cached copy of the data it is working on, and when we synchronize using Synchronzied, the real synchronization is the memory block that represents the locked object in a different thread (the replica data is kept synchronized with the main memory, Now you know why you need to sync this vocabulary. Simply put, after the synchronization block or synchronization method is executed, any modifications made to the locked object are written back to the main memory before releasing the lock, and the data of the locked object is read from the main memory after the lock is entered into the synchronized block. The data copy of the thread holding the lock must be synchronized with the data view in the main memory.

Here are a few specific examples to illustrate the synchronized of the various situations.

Synchronized synchronization method

First, let's look at examples of synchronization methods:

public class SynchronizedTest1 extends Thread 
{ 
  private synchronized void Testsynchronizedmethod () 
  { 
    for (int i = 0; i < i++) 
    {System.out.println ( 
      thread.currentthread). GetName () 
          + " Testsynchronizedmethod: "+ i); 
 
      Try 
      { 
        thread.sleep (); 
      } 
      catch (interruptedexception e) 
      { 
        e.printstacktrace (); 
 
  }}} @Override public 
  Void Run () 
  { 
    testsynchronizedmethod (); 
  } 
 
  public static void Main (string[] args) 
  { 
 
        SynchronizedTest1 t = new SynchronizedTest1 (); 
    T.start (); 
    T.testsynchronizedmethod (); 
  } 
 

The result of running the program output is:

Main testsynchronizedmethod:0 
main testsynchronizedmethod:1 main 
testsynchronizedmethod:2 
main Testsynchronizedmethod:3 
main testsynchronizedmethod:4 main 
testsynchronizedmethod:5 
main Testsynchronizedmethod:6 
main testsynchronizedmethod:7 main 
testsynchronizedmethod:8 
main Testsynchronizedmethod:9 
Thread-0 testsynchronizedmethod:0 
Thread-0 testsynchronizedmethod:1 
Thread-0 testsynchronizedmethod:2 
Thread-0 testsynchronizedmethod:3 
Thread-0 testsynchronizedmethod:4 
Thread-0 Testsynchronizedmethod:5 
Thread-0 testsynchronizedmethod:6 
Thread-0 testsynchronizedmethod:7 
Thread-0 testsynchronizedmethod:8 
Thread-0 Testsynchronizedmethod:9 

You can see that the Testsynchronizedmethod method executes synchronously between two threads.

If you modify the main method to look like this at this point, two threads are not synchronized, because the Sync monitor for two threads is not the same object and cannot play a role in synchronization.

public static void Main (string[] args) 
  { 
    Thread t = new SynchronizedTest1 (); 
    T.start (); 
     
    Thread T1 = new SynchronizedTest1 (); 
    T1.start (); 
  } 

The output now looks like this:

Thread-0 testsynchronizedmethod:0 
Thread-1 testsynchronizedmethod:0 
Thread-0 testsynchronizedmethod:1 
Thread-1 testsynchronizedmethod:1 
Thread-0 testsynchronizedmethod:2 
Thread-1 testsynchronizedmethod:2 
Thread-0 testsynchronizedmethod:3 
Thread-1 Testsynchronizedmethod:3 
Thread-0 testsynchronizedmethod:4 
Thread-1 testsynchronizedmethod:4 
Thread-0 testsynchronizedmethod:5 
Thread-1 Testsynchronizedmethod:5 
Thread-0 testsynchronizedmethod:6 
Thread-1 testsynchronizedmethod:6 
Thread-0 testsynchronizedmethod:7 
Thread-1 Testsynchronizedmethod:7 
Thread-0 testsynchronizedmethod:8 
Thread-1 testsynchronizedmethod:8 
Thread-0 testsynchronizedmethod:9 
Thread-1 Testsynchronizedmethod:9 

If you want the modified main method to be able to run synchronously between two threads, you need to declare the Testsynchronizedmethod method as a static method, so that the two-thread monitor is the same object (class object) and can be executed synchronously. The modified code looks like this:

public class SynchronizedTest1 extends Thread 
{ 
  private static synchronized void Testsynchronizedmethod () 
  {for 
    (int i = 0; i < i++) 
    {System.out.println ( 
      thread.currentthread (). GetName () 
          + " Testsynchronizedmethod: "+ i); 
 
      Try 
      { 
        thread.sleep (); 
      } 
      catch (interruptedexception e) 
      { 
        e.printstacktrace (); 
 
  }}} @Override public 
  Void Run () 
  { 
    testsynchronizedmethod (); 
  } 
 
  public static void Main (string[] args) 
  { 
    Thread t = new SynchronizedTest1 (); 
    T.start (); 
     
    Thread T1 = new SynchronizedTest1 (); 
    T1.start (); 
  } 
 

The output results are as follows:

Thread-0 testsynchronizedmethod:0 
Thread-0 testsynchronizedmethod:1 
Thread-0 testsynchronizedmethod:2 
Thread-0 Testsynchronizedmethod:3 
Thread-0 testsynchronizedmethod:4 
Thread-0 testsynchronizedmethod:5 
Thread-0 testsynchronizedmethod:6 
Thread-0 Testsynchronizedmethod:7 
Thread-0 testsynchronizedmethod:8 
Thread-0 testsynchronizedmethod:9 
Thread-1 testsynchronizedmethod:0 
Thread-1 testsynchronizedmethod:1 
Thread-1 testsynchronizedmethod:2 
Thread-1 testsynchronizedmethod:3 
Thread-1 testsynchronizedmethod:4 
Thread-1 Testsynchronizedmethod:5 
Thread-1 testsynchronizedmethod:6 
Thread-1 testsynchronizedmethod:7 
Thread-1 testsynchronizedmethod:8 
Thread-1 Testsynchronizedmethod:9 

The synchronization block is similar to the synchronization method, except that the synchronization block reduces the granularity of the synchronization control, so that the efficiency of multithreaded parallel execution can be better played.
Use the This object to control synchronization between instances of the same object:

public class SynchronizedTest2 extends Thread 
{ 
  private void Testsynchronizedblock () 
  { 
    synchronized ( This) 
    {for 
      (int i = 0; i < i++) 
      {System.out.println ( 
        thread.currentthread (). GetName () 
            + " Testsynchronizedblock: "+ i); 
 
        Try 
        { 
          thread.sleep (); 
        } 
        catch (interruptedexception e) 
        { 
          e.printstacktrace (); 
 
  }}} @Override public 
  Void Run () 
  { 
    testsynchronizedblock (); 
  } 
 
  public static void Main (string[] args) 
  { 
    SynchronizedTest2 t = new SynchronizedTest2 (); 
    T.start (); 
 
    T.testsynchronizedblock (); 
  } 
 

Output results:

Main testsynchronizedblock:0 
main testsynchronizedblock:1 main 
testsynchronizedblock:2 
main Testsynchronizedblock:3 
main testsynchronizedblock:4 main 
testsynchronizedblock:5 
main Testsynchronizedblock:6 
main testsynchronizedblock:7 main 
testsynchronizedblock:8 
main Testsynchronizedblock:9 
Thread-0 testsynchronizedblock:0 
Thread-0 testsynchronizedblock:1 
Thread-0 testsynchronizedblock:2 
Thread-0 testsynchronizedblock:3 
Thread-0 testsynchronizedblock:4 
Thread-0 Testsynchronizedblock:5 
Thread-0 testsynchronizedblock:6 
Thread-0 testsynchronizedblock:7 
Thread-0 testsynchronizedblock:8 
Thread-0 Testsynchronizedblock:9 

Use the class object to control synchronization between different instances:

public class SynchronizedTest2 extends Thread 
{ 
  private void Testsynchronizedblock () 
  { 
    synchronized ( Synchronizedtest2.class) 
    {for 
      (int i = 0; i < i++) 
      { 
        System.out.println (Thread.CurrentThread () . GetName () 
            + "Testsynchronizedblock:" + i); 
 
        Try 
        { 
          thread.sleep (); 
        } 
        catch (interruptedexception e) 
        { 
          e.printstacktrace (); 
 
  }}} @Override public 
  Void Run () 
  { 
    testsynchronizedblock (); 
  } 
 
  public static void Main (string[] args) 
  { 
    Thread t = new SynchronizedTest2 (); 
    T.start (); 
 
    Thread t2 = new SynchronizedTest2 (); 
    T2.start (); 
  } 
 

Output results:

Thread-0 testsynchronizedblock:0 
Thread-0 testsynchronizedblock:1 
Thread-0 
testsynchronizedblock:2 Thread-0 testsynchronizedblock:3 
Thread-0 testsynchronizedblock:4 
Thread-0 
testsynchronizedblock:5 Thread-0 testsynchronizedblock:6 
Thread-0 testsynchronizedblock:7 
Thread-0 
testsynchronizedblock:8 Thread-0 testsynchronizedblock:9 
Thread-1 testsynchronizedblock:0 
Thread-1 testsynchronizedblock:1 
Thread-1 Testsynchronizedblock:2 
Thread-1 testsynchronizedblock:3 
Thread-1 testsynchronizedblock:4 
Thread-1 testsynchronizedblock:5 
Thread-1 Testsynchronizedblock:6 
Thread-1 testsynchronizedblock:7 
Thread-1 testsynchronizedblock:8 


When using the Synchronized keyword for synchronous control, be sure to grasp the object monitor, only the process that gets the monitor can run, and others need to wait for the monitor. Any non-null object can act as an object monitor, and when synchronized acts on a method, the object instance (this) is locked, and the object's corresponding class instance is locked when acting on a static method.

Two threads simultaneous access to an object's synchronization method
when two concurrent threads access synchronization methods for the same object, only one thread can be executed. Another thread must wait until the current thread has finished executing this to execute.

public class Twothread {public
  static void Main (string[] args) {
    final twothread twothread = new Twothread (); 
   
    thread T1 = new Thread (new Runnable () {public
      void run () {
        twothread.syncmethod ();
      }
    }, "A");
    Thread t2 = new Thread (new Runnable () {public
      void run () {
        twothread.syncmethod ();
      }
    }, "B");

    T1.start ();
    T2.start ();
  }

  Public synchronized void Syncmethod () {for
    (int i = 0; i < 5; i++) {
      System.out.println (thread.currentthread (). GetName () + ":" + i);
      try {
        thread.sleep;
      } catch (Interruptedexception IE) {
      }

}}


   

Output results:

a:0
a:1
a:2
a:3
a:4
b:0
b:1 b:2 b:3 b:4

Two threads are accessing the synchronization method of two objects
in this case, the synchronized does not work, as with the normal method. Since the corresponding lock is the individual object.

public class Twoobject {public
  static void Main (string[] args) {
    final twoobject object1 = new Twoobject ();
    thread T1 = new Thread (new Runnable () {public
      void run () {
        object1.syncmethod ();
      }
    }, "Object1");
    T1.start ();

    Final Twoobject object2 = new Twoobject ();
    Thread t2 = new Thread (new Runnable () {public
      void run () {
        object2.syncmethod ();
      }
    }, "Object2"); C16/>t2.start ();
  }

  Public synchronized void Syncmethod () {for
    (int i = 0; i < 5; i++) {
      System.out.println (thread.currentthread (). GetName () + ":" + i);
      try {
        thread.sleep;
      } catch (Interruptedexception IE) {
      }

}}

One of the possible output results:

object2:0
object1:0
object1:1
object2:1
object2:2
object1:2
: 3
object1:4
object2:4

Two threads are accessing the static method of synchronized
in this case, because the lock is class, at any time, the static method has only one thread to execute.

Simultaneous access synchronization and non-synchronous methods
When one thread accesses a synchronization method of an object, another thread can still access the asynchronous methods in that object.

 public class Syncandnosync {public static void main (string[] args) {final Syncandnosync

    Syncandnosync = new Syncandnosync ();
      thread T1 = new Thread (new Runnable () {public void run () {Syncandnosync.syncmethod ());
    }, "A");

    T1.start ();
      Thread t2 = new Thread (new Runnable () {public void run () {Syncandnosync.nosyncmethod ());
    }, "B");
  T2.start (); synchronized void Syncmethod () {for (int i = 0; i < 5; i++) {System.out.println (Thread.currentt
      Hread (). GetName () + "at Syncmethod ():" + i);
      try {thread.sleep (500); 
      The catch (Interruptedexception IE) {}} is public void Nosyncmethod () {for (int i = 0; i < 5; i++) {
      System.out.println (Thread.CurrentThread (). GetName () + "at Nosyncmethod ():" + i);
      try {thread.sleep (500); ' catch (Interruptedexception IE) {}}} ' 

A possible output result:

b at Nosyncmethod (): 0
A at Syncmethod (): 0
B at Nosyncmethod (): 1
A at Syncmethod (): 1
B at Nosyncmethod ( ): 2
A at Syncmethod (): 2
B at Nosyncmethod (): 3
A at Syncmethod (): 3
A at Syncmethod (): 4
B at NoSync Method (): 4

Accessing different synchronization methods for the same object
when one thread accesses the synchronization method A of an object, access to all other synchronization methods in that object is blocked by other threads. Because the first thread has acquired an object lock and the other threads do not get a lock, it accesses a different method but does not acquire a lock and is inaccessible.

 public class Twosyncmethod {public static void main (string[] args) {final Twosyncmethod

    Twosyncmethod = new Twosyncmethod ();
      thread T1 = new Thread (new Runnable () {public void run () {twosyncmethod.syncmethod1 ());
    }, "A");

    T1.start ();
      Thread t2 = new Thread (new Runnable () {public void run () {twosyncmethod.syncmethod2 ());
    }, "B");
  T2.start (); synchronized void SyncMethod1 () {for (int i = 0; i < 5; i++) {System.out.println (thread.current
      Thread (). GetName () + "at SyncMethod1 ():" + i);
      try {thread.sleep (500); The catch (Interruptedexception IE) {}} is public synchronized void SyncMethod2 () {for (int i = 0; I &l T 5;
      i++) {System.out.println (Thread.CurrentThread (). GetName () + "at SyncMethod2 ():" + i);
      try {thread.sleep (500); ' catch (Interruptedexception IE) {}}} ' 

Output results:

A at syncMethod1 (): 0
A at syncMethod1 (): 1
A at SyncMethod1 (): 2
A at SyncMethod1 (): 3
A at syncMethod1 () : 4
B at SyncMethod2 (): 0
B at SyncMethod2 (): 1
B at SyncMethod2 (): 2
B at SyncMethod2 (): 3
B at SYNCM ETHOD2 (): 4

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.