Synchronization of threads (Solving multithreading safety problems)

Posted by mtlhd on Mon, 31 Jan 2022 12:51:54 +0100

Reasons for safety problems in multithreading:

When multiple statements are operating on the same thread to share data, one thread only executes part of multiple statements, but not yet
 
After execution, another thread participates in the execution. The error that caused the shared data.
 
resolvent:
 
For statements with multiple operations sharing data, only one thread can complete the execution. During the execution, other threads cannot
 
Participate in the implementation.
 
Java provides a special solution to the security problem of multithreading: synchronization mechanism.
 
Method 1: synchronize code blocks
 
synchronized{
/ / code to be synchronized
}
 
explain:
 
1. The code that operates the shared data is the code that needs to be synchronized (be careful not to include more or less);
 
2. Shared data: variables operated by multiple threads;
 
3. Synchronization monitor: commonly known as lock, the object of any class can act as a lock (it is required that each thread must share a lock);
 
4. In the way of implementing the Runnab interface to create multithreading, you can consider using this as the synchronization monitor and inheriting the Thread class
 
In the way of creating multithreading, you can consider classes class as the synchronization monitor.
 
The following is a simple question about selling tickets in multiple windows
 
class Window implements Runnable{//Implement the Runnable method to create multithreading

    private static int ticket = 100;//Number of votes

    @Override
    public void run() {//Override run method
        while (true){
          synchronized (this) {//Package the code that operates on shared data with synchronized
              if (ticket > 0) {
                  //The name of the current thread
                  System.out.println(Thread.currentThread().getName() + ":Ticket No.:" + ticket);

                  ticket--;
              } else {
                  break;
              }
          }
        }
    }
}

At this time, for statements that operate on shared data, only when one thread finishes executing and releases the lock can other threads enter.

Method 2: use synchronization method

When the code that operates on shared data is completely declared in a method, this method can be set to synchronous.

be careful:

1. The synchronization method still involves the synchronization monitor, but we don't need to display the declaration;

2. Non static synchronization method. The synchronization monitor is this

Static synchronization method. The synchronization monitor is the current class itself (class. Class)

This is a non static synchronization method

//Implement Runnable interface to create multithreading
class Window1 implements Runnable{

    private static int ticket = 100;//Number of votes

    @Override
    public void run() {//Override run method
        while (true){
            show();//This method is a method of operating shared data
        }
    }

    private synchronized void  show(){//Sync monitor is this

            if (ticket > 0) {

                System.out.println(Thread.currentThread().getName() + ":Ticket No.:" + ticket);

                ticket--;
            }

        }
}

 

This is a static synchronization method

//Inherit the Thread class to create a multithread
class Window2 extends Thread {

    private static int ticket = 100;//Number of votes

    @Override
    public void run() {
        while (true){
            show();//This method is a method of operating shared data
        }
    }

    private  static synchronized void  show(){//The synchronization monitor is window2 class

        if (ticket > 0) {

            System.out.println(Thread.currentThread().getName() + ":Ticket No.:" + ticket);

            ticket--;
        }
    }
}

 

Mode 3: lock

class A{
private final ReentrantLock lock = new ReenTrantLock();
public void m(){
lock.lock();
try{
// Thread safe code ;
}
finally{
lock.unlock();
}
}
}
 
explain:
 
1. From JDK 5.0 Start, Java Provides a more powerful thread synchronization mechanism - The synchronization is realized by explicitly defining the synchronization lock object
 
Step. Sync Lock use Lock Object acts as;
 
2, java.util.concurrent.locks.Lock Interface is used to control multiple threads to access shared resources Tools. Locks provide common
 
For exclusive access to shared resources, only one thread can Lock the Lock object at a time. The thread should obtain the Lock before accessing the shared resources
 
Lock object;
 
3. The ReentrantLock class implements Lock, which has the same concurrency and memory semantics as synchronized
 
ReentrantLock is commonly used in process safety control, which can explicitly add and release locks.
class Windowlock implements Runnable{

    private  int trick = 100;
//    Instantiate ReentrantLock
    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {

        while (true) {
            try {
                  //Call lock method
                    lock.lock();
                    if(trick > 0){

                        System.out.println(Thread.currentThread().getName() + ":" + trick);
                        trick--;
                    }else{
                        break;
                    }
            } finally {
//Unlock
                lock.unlock();
            }
        }

    }
}

 

Comparison between synchronized and lock:
 
1. Lock is an explicit lock (manually open and close the lock, don't forget to close the lock), synchronized It's an implicit lock. It's out of scope automatically
 
Release;
 
2. Lock has only code block lock, synchronized There are code block locks and method locks;
 
3. Use Lock Lock, JVM It will take less time to schedule threads for better performance. And it has better scalability (providing more
 
Multiple subclasses)
 
Priority:
 
lock - > synchronization code block - > synchronization method

Topics: Java Multithreading