Java thread synchronization synchronization method instance detail

  • 2020-07-21 07:54:00
  • OfStack

Thread synchronization is a means to ensure multithread safe access to competing resources.

Thread synchronization is the difficulty of Java multithreaded programming. Developers are often confused about what is a competing resource, when to consider synchronization, how to synchronize and so on. Of course, there is no clear answer to these questions, but some principle questions need to be considered.

For synchronization, the following two operations need to be done in the specific Java code:

Identify competing access resources as private;

Synchronize code that modifies variables using the synchronized keyword to synchronize methods or code.

Of course, this is not the only way to control concurrency security.

synchronized keyword instructions

synchronized can only mark non-abstract methods and cannot identify member variables.

To demonstrate the use of the synchronization method, a credit card account was built with an initial credit of 100w and then simulated overdrafts, deposits, and other operations. Obviously, the bank account User object is a competing resource, and multiple concurrent operations are on the account method oper(int x), which should of course be synchronized and the account balance set to a private variable,

Direct access is prohibited.


/** 
* Java Threads: Synchronization of threads  
* 
* @author leizhimin 2009-11-4 11:23:32 
*/ 
public class Test { 
  public static void main(String[] args) { 
    User u = new User(" zhang 3", 100); 
    MyThread t1 = new MyThread(" thread A", u, 20); 
    MyThread t2 = new MyThread(" thread B", u, -60); 
    MyThread t3 = new MyThread(" thread C", u, -80); 
    MyThread t4 = new MyThread(" thread D", u, -30); 
    MyThread t5 = new MyThread(" thread E", u, 32); 
    MyThread t6 = new MyThread(" thread F", u, 21); 
    t1.start(); 
    t2.start(); 
    t3.start(); 
    t4.start(); 
    t5.start(); 
    t6.start(); 
  } 
} 
class MyThread extends Thread { 
  private User u; 
  private int y = 0; 
   MyThread(String name, User u, int y) { 
    super(name); 
    this.u = u; 
    this.y = y; 
  } 
  public void run() { 
    u.oper(y); 
  } 
} 
class User { 
  private String code; 
  private int cash; 
  User(String code, int cash) { 
    this.code = code; 
    this.cash = cash; 
  } 
  public String getCode() { 
    return code; 
  } 
  public void setCode(String code) { 
    this.code = code; 
  } 
  /** 
   *  Business methods  
   * @param x  add x Ten thousand yuan  
   */ 
  public synchronized void oper(int x) { 
    try { 
      Thread.sleep(10L); 
      this.cash += x; 
      System.out.println(Thread.currentThread().getName() + " Run over, add" " + x + " ", the current user account balance is: " + cash); 
      Thread.sleep(10L); 
    } catch (InterruptedException e) { 
      e.printStackTrace(); 
    } 
  } 
  @Override 
  public String toString() { 
    return "User{" + 
        "code='" + code + '\'' + 
        ", cash=" + cash + 
        '}'; 
  } 
} 

Output results:


 thread A Run over, add" 20 ", the current user account balance is: 120 
 thread F Run over, add" 21 ", the current user account balance is: 141 
 thread E Run over, add" 32 ", the current user account balance is: 173 
 thread C Run over, add" -80 ", the current user account balance is: 93 
 thread B Run over, add" -60 ", the current user account balance is: 33 
 thread D Run over, add" -30 ", the current user account balance is: 3 

The other example, out of sync, is to remove the synchronized modifier of oper(int x) method, and then run the program. The result is as follows:


 thread A Run over, add" 20 ", the current user account balance is: 61 
 thread D Run over, add" -30 ", the current user account balance is: 63 
 thread B Run over, add" -60 ", the current user account balance is: 3 
 thread F Run over, add" 21 ", the current user account balance is: 61 
 thread E Run over, add" 32 ", the current user account balance is: 93 
 thread C Run over, add" -80 ", the current user account balance is: 61 

Obviously, the above result is incorrect because multiple threads accessed the competing resource u concurrently and made changes to the attributes of u.

See the importance of synchronization.

Note:

As mentioned above, when a thread exits a synchronized method, it releases the lock on the object to which the method belongs, but it should also be noted that a specific method can also be used to schedule a thread in a synchronized method. These methods come from the java.lang.Object class.


void notify()  
      Wakes up a single thread waiting on this object monitor.   
void notifyAll()  
      Wakes up all threads waiting on this object monitor.   
void wait()  
      Causes the current thread to wait until another thread calls this object  notify()  Method or  notifyAll()  Methods.   
void wait(long timeout)  
      Causes the current thread to wait until another thread calls this object  notify()  Method or  notifyAll()  Method, or more than a specified amount of time.   
void wait(long timeout, int nanos)  
      Causes the current thread to wait until another thread calls this object  notify()  Method or  notifyAll()  Method, or some other thread interrupts the current thread, or has exceeded an actual amount of time  

In combination with the above methods, it is very important to deal with multi-threading synchronization and mutual exclusion. The famous producer-consumer example is a classic example of any language where multi-threading is a must.

I hope this article has been helpful to you


Related articles: