About Java Multithreading - ---(3, Synchronization and Deadlock)

Keywords: network Database

1. The role of thread synchronization

2. Synchronization Block and Synchronization Method

3. Deadlock

In multi-threaded development, synchronization and deadlock are very important, so the problem arises, for these two things, we need to think about a few issues.

1, where the code needs synchronization; 2, how to achieve synchronization; 3, what side effects will occur after synchronization.

1. Why synchronize when problems arise? (What is synchronization and why synchronization is necessary)

For example, selling train tickets, selling train tickets will have multiple ticket stations, the number of seats on a train is fixed, each ticket point can be understood as each thread, that is to say, all threads have the same ticket source, while not a seat to sell two tickets.

class MyThread implements Runnable{
    private int ticket = 5 ;    // Suppose there are five tickets altogether.
    public void run(){
        for(int i=0;i<100;i++){
            if(ticket>0){   // There are still tickets.
                System.out.println("Ticket sales: ticket = " + ticket-- );
            }
        }
    }
};
public class SyncDemo01{
    public static void main(String args[]){
        MyThread mt = new MyThread() ;  // Define Thread Objects
        Thread t1 = new Thread(mt) ;    // Define Thread objects
        Thread t2 = new Thread(mt) ;    // Define Thread objects
        Thread t3 = new Thread(mt) ;    // Define Thread objects
        t1.start() ;
        t2.start() ;
        t3.start() ;
    }
};

In practice, ticketing information is stored in the database, reading information from the database and displaying it on the ticketing equipment through the network. In this process, there must be time delay.

class MyThread implements Runnable{
    private int ticket = 5 ;    // Suppose there are five tickets altogether.
    public void run(){
        for(int i=0;i<100;i++){
            if(ticket>0){   // There are still tickets.
                try{
                    Thread.sleep(300) ; // Add Delay
                }catch(InterruptedException e){
                    e.printStackTrace() ;
                }
                System.out.println("Ticket sales: ticket = " + ticket-- );
            }
        }
    }
};
public class SyncDemo01{
    public static void main(String args[]){
        MyThread mt = new MyThread() ;  // Define Thread Objects
        Thread t1 = new Thread(mt) ;    // Define Thread objects
        Thread t2 = new Thread(mt) ;    // Define Thread objects
        Thread t3 = new Thread(mt) ;    // Define Thread objects
        t1.start() ;
        t2.start() ;
        t3.start() ;
    }
};

Find out, broken, sold a negative number of tickets, code problems ah... What's the matter with him in this situation? Why is this problem with delays?

Analyse this question:

Well, the code is written to solve practical problems. It's not for fun. In fact, there will be all kinds of complex situations, which will lead to the network blockage, so we can't help delaying it.

So in the case of delays, how can we solve this problem perfectly?

2. Synchronization problem solving: (Synchronization effect)

To solve the problem of synchronization operation of resource sharing, synchronization code block and synchronization method can be used.

Code blocks are divided into four types:
Ordinary code block: is directly defined in the method;
Fast construction: in directly defined classes; (prior to construction method execution, repeated calls)
Static block: declared using the static keyword (prior to fast execution of construction, only once)
Synchronized Code Block: A code block declared using synchronized keywords, called Synchronized Code Block;

Synchronizing code blocks to solve problems


When synchronizing, it is necessary to specify the synchronized object. Generally, the current object will be used as the synchronized object, which is represented by this.

class MyThread implements Runnable{
    private int ticket = 5 ;    // Suppose there are five tickets altogether.
    public void run(){
        for(int i=0;i<100;i++){
            synchronized(this){ // Synchronize the current object
                if(ticket>0){   // There are still tickets.
                    try{
                        Thread.sleep(300) ; // Add Delay
                    }catch(InterruptedException e){
                        e.printStackTrace() ;
                    }
                    System.out.println("Ticket sales: ticket = " + ticket-- );
                }
            }
        }
    }
};
public class SyncDemo02{
    public static void main(String args[]){
        MyThread mt = new MyThread() ;  // Define Thread Objects
        Thread t1 = new Thread(mt) ;    // Define Thread objects
        Thread t2 = new Thread(mt) ;    // Define Thread objects
        Thread t3 = new Thread(mt) ;    // Define Thread objects
        t1.start() ;
        t2.start() ;
        t3.start() ;
    }
};

From the running results, we can find that the synchronization operation is successfully added, so there will be no negative number, but the efficiency of program execution is significantly reduced. When synchronization operation is not added, it is asynchronous execution, and asynchronous execution is obviously faster.

Synchronization Solution

class MyThread implements Runnable{
    private int ticket = 5 ;    // Suppose there are five tickets altogether.
    public void run(){
        for(int i=0;i<100;i++){
            this.sale() ;   // Call the synchronization method
        }
    }
    public synchronized void sale(){    // Declare synchronization method
        if(ticket>0){   // There are still tickets.
            try{
                Thread.sleep(300) ; // Add Delay
            }catch(InterruptedException e){
                e.printStackTrace() ;
            }
            System.out.println("Ticket sales: ticket = " + ticket-- );
        }

    }
};
public class SyncDemo03{
    public static void main(String args[]){
        MyThread mt = new MyThread() ;  // Define Thread Objects
        Thread t1 = new Thread(mt) ;    // Define Thread objects
        Thread t2 = new Thread(mt) ;    // Define Thread objects
        Thread t3 = new Thread(mt) ;    // Define Thread objects
        t1.start() ;
        t2.start() ;
        t3.start() ;
    }
};

3. Side effects of synchronization - deadlock

1. When sharing resources, synchronous operation is needed (to solve the problem caused by delay).
2. If synchronization is excessive, deadlock will occur.

Deadlock usually means to wait for each other. It is a problem that arises when the program runs.

For example, the above example of Zhang Sanli-si implements the code:

class Zhangsan{ // Definition of Zhang Three Categories
    public void say(){
        System.out.println("Zhang San said to Li Si, "If you give me a picture, I'll give you the book."") ;
    }
    public void get(){
        System.out.println("Zhang San got the picture.") ;
    }
};
class Lisi{ // Definition of Lie's Four Categories
    public void say(){
        System.out.println("Li Si said to Zhang San, "If you give me a book, I'll give you a picture."") ;
    }
    public void get(){
        System.out.println("Li Si got the book.") ;
    }
};
public class ThreadDeadLock implements Runnable{
    private static Zhangsan zs = new Zhangsan() ;       // Instantiating static Objects
    private static Lisi ls = new Lisi() ;       // Instantiating static Objects
    private boolean flag = false ;  // Declare the flag and judge which speaks first
    public void run(){  // Override run() method
        if(flag){
            synchronized(zs){   // Synchronized Zhang San
                zs.say() ;
                try{
                    Thread.sleep(500) ;
                }catch(InterruptedException e){
                    e.printStackTrace() ;
                }
                synchronized(ls){
                    zs.get() ;
                }
            }
        }else{
            synchronized(ls){
                ls.say() ;
                try{
                    Thread.sleep(500) ;
                }catch(InterruptedException e){
                    e.printStackTrace() ;
                }
                synchronized(zs){
                    ls.get() ;
                }
            }
        }
    }
    public static void main(String args[]){
        ThreadDeadLock t1 = new ThreadDeadLock() ;      // Controlling Zhang San
        ThreadDeadLock t2 = new ThreadDeadLock() ;      // Controlling Li Si
        t1.flag = true ;
        t2.flag = false ;
        Thread thA = new Thread(t1) ;
        Thread thB = new Thread(t2) ;
        thA.start() ;
        thB.start() ;
    }
};


The above is the operation state of deadlock, which is waiting for the answer from each other.

Summary:

1. When multiple threads access the same resource, they need to operate synchronously.
2. synchronized keyword is used to accomplish synchronization.
3. Synchronization is divided into synchronization block and synchronization method.
4. Excessive synchronization may lead to deadlock, which is a manifestation of the program at run time.

The reason of synchronization is to solve the problem of access to the same resource caused by delay; the problem of too much synchronization also leads to deadlock, which is also caused by delay - so, fundamentally speaking, if it is a network service, improving the network speed is the fundamental solution, and human beings have been committed to the research of 4g, 5g, 8g. Ah, if it's a local service, the key is to improve the efficiency of hardware execution and concurrency --- dual-core CPU, quad-core CPU, i3, i7, i9 series CPU, awesome,,, human wisdom is infinite....

Posted by JetJagger on Wed, 19 Jun 2019 10:45:03 -0700