[Java Multithreading] Synchronized code blocks handle thread safety issues

Question: Create three windows to sell tickets, and the total number of tickets is 100. 
1. Question: During the process of buying tickets, there are duplicate tickets and wrong tickets --> there is a thread security problem. 
2. The reason for the problem: when a thread In the process of operating the ticket, when the operation has not been completed, other threads participate and also operate the ticket 
3. How to solve: When a thread a is operating the ticket, other threads cannot participate until the thread a completes the operation of the ticket, other 
  threads Only then can you start to operate the ticket. In this case, even if thread a is blocked, it cannot be changed. 
Take things in life as an example:
If you are going to the toilet, another person is in a hurry and rushes into the toilet where you are. This presents a security problem. How should it be solved? 
Answer: Lock the toilet door 4. In Java, we use a synchronization mechanism to solve thread security issues. 
==================================================== ========================================   Method 1: Synchronization code block synchronized (synchronization monitor) { 
       //Code that needs to be synchronized 
   } 
   Description: 1. The code that operates on shared data is the code that needs to be synchronized 
         2. Shared data: variables that multiple threads operate together. For example: ticket is shared data 
         3. Synchronization monitor. Common name: lock. Objects of any class can act as lock requirements: multiple threads must share the same lock


   
           

 

Synchronized code blocks handle the thread safety issues of implementing Runnable

code show as below:

class Window1 implements Runnable{

    private int ticket = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while (true){
            synchronized (obj) {
                if (ticket > 0){
                    System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ticket--;
                }else {
                    break;
                }
            }
        }
    }
}
public class WindowTest1{
    public static void main(String[] args) {
        Window1 w = new Window1();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();

    }
}

 According to multiple runs, no wrong tickets or duplicate tickets were found

Synchronized code blocks handle thread safety issues inherited from the Thread class

We first imitate the above method and run the test;

code show as below:


class Window extends Thread{
    private static int ticket = 100;
    private Object obj = new Object();
    @Override
    public void run() {
        while (true){
            synchronized (obj){
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName() + "卖票,票号为:" + ticket);
                    ticket --;
                }else {
                    break;
                }
            }
        }
    }
}
public class WindowTest {
    public static void main(String[] args) {
        Window t1 = new Window();
        Window t2 = new Window();
        Window t3 = new Window();

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();

    }
}
As shown in the figure, 

we can see that there are still heavy tickets. Because it is described above. Requirements: Multiple threads must share the same lock
, so we can add static 
code as shown below
class Window extends Thread{
    private static int ticket = 100;
    private static Object obj = new Object();
    @Override
    public void run() {
        while (true){
            synchronized (obj){
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName() + "卖票,票号为:" + ticket);
                    ticket --;
                }else {
                    break;
                }
            }
        }
    }
}
public class WindowTest {
    public static void main(String[] args) {
        Window t1 = new Window();
        Window t2 = new Window();
        Window t3 = new Window();

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();

    }
}
There is no problem running. 
==================================================== ========================================= 
We see "requirements: multiple threads must share the same Put the lock" in the synchronization code block to deal with the thread safety issue of implementing Runnable. We can change the synchronization monitor to "this"
 at this time: the only object of Window1
class Window1 implements Runnable{

    private int ticket = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while (true){
            synchronized (this){//此时的this:唯一的Window1的对象 synchronized (obj) {
                if (ticket > 0){
                    System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ticket--;
                }else {
                    break;
                }
            }
        }
    }
}
public class WindowTest1{
    public static void main(String[] args) {
        Window1 w = new Window1();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();

    }
}
Think about whether the synchronization monitor can also be changed to "this" in the synchronization code block to deal with the thread safety issue of inheriting the Thread class. 
As shown in the figure below, window creates three objects, so the synchronization monitor cannot be changed to this. But there is also an easy way, change the sync monitor to "Window.class"

synchronized (Window.class){
}
==================================================== ======================================== 
Summary: 
The synchronization method solves the existing security problems. ---Benefits 
When operating synchronous code, only one thread can participate, while other threads wait. It is equivalent to a single-threaded process with low efficiency. --- LIMITATIONS Thanks for watching! ! !

 

 

Guess you like

Origin blog.csdn.net/qq_64976935/article/details/128879882