[Java] Java basic knowledge of thread safety issues

       Thread safety : Inthe case of high concurrency , threads and threads may cause logical problems that should not occur. One thread will affect another thread. This is a thread safety issue.

       High concurrency : Refers to multiple threads executing the same task at the same time in a short period of time, which is called high concurrency. For example: Double Eleven, 12306 ticket grab service, etc.

        Thread safety issues: visibility, order and atomicity.

1. Visibility

        One thread cannot see another thread's data operations, resulting in data errors.

public class AAA extends Thread {
    //成员变量
    static int a = 0;
    @Override
    public void run() {
        System.out.println("AAA开始执行了a=0");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        //修改a的值
        a = 10;
        System.out.println("a的值已经是10了a=10");
    }
}

public class BBB extends Thread {
    @Override
    public void run() {
        while(true){
            if(AAA.a == 10){
                System.out.println("我看到了a的值是10");
                break;
            }else{
                //System.out.println("a不是10");
            }
        }
    }
}

public class Test01 {
    public static void main(String[] args) {
        //创建线程对象
        AAA a = new AAA();
        a.start();
        BBB b = new BBB();
        b.start();
    }
}
执行效果:
	在2秒之后,AAA线程已经把变量改成10了,但是BBB线程没有看到。

        This is because in the first two seconds when the AAA thread sleeps, the BBB thread has obtained the value of countless a variable, the value of this variable is always 0, and there is no operation in the loop, the system thinks this operation is no Meaningful operation, the thread will think that the value of a is 0 and will not change, and the thread will not go to the method area to get the value of a

2. Orderliness:

        Refers to the code rearrangement problem that may occur during the execution of the code. Rearrangement means that the program thinks that some codes have no order in the execution process, but the rearrangement of one thread may cause other threads to affect it.

            

 Order problems are difficult to demonstrate through code. As can be seen from the above example, the different execution order of a and b in thread one can easily lead to different results of C.

3. Atomicity

        Between thread and thread, the original inseparable code during operation will affect the running data (a++, a--)

package com.itheima_01;
public class CCC extends Thread {
    //被当前类的所有对象共享
    static int a = 0;
    @Override
    //每执行一次run方法a加10000次
    public void run() {
        //循环
        for (int i = 0; i < 10000; i++) {
            a++;
        }
        System.out.println("循环结束了");
    }
}

public class Test02 {
    public static void main(String[] args) throws InterruptedException {
        //创建线程
        CCC c = new CCC();
        c.start();
        //创建线程
        CCC c2 = new CCC();
        c2.start();
        //main线程睡觉
        Thread.sleep(2000);

        //打印a变量
        System.out.println(CCC.a);  //小于20000
    }
}

The following figure analysis:

              

         The execution of a++ code can be divided into three steps: get the value of a--"add 1 to the variable--"assign the value back

         When A grabs the thread first, and executes the a++ code at this time, suppose that when it is executed in step 2, at this time, the B thread grabs the CPU and also executes an a++ operation, and the assignment has ended, but this When, thread A does not know that thread B has executed a++ for assignment, thread A continues to use the value of a at the beginning (that is, 0) to perform a++ operation, causing both threads to perform a++ operation, but the result is still Is 1 .

Solutions to thread safety issues:

1) Volatile keyword: It can solve the problem of visibility and order of threads, allowing each variable to get a new value, and preventing the code from rearranging

2) AtomicInteger is called an atomic class, which can solve all the problems just now. Visibility, order, atomicity.

package com.itheima_01;
import java.util.concurrent.atomic.AtomicInteger;
public class CCC extends Thread {

    //被当前类的所有对象共享
    //static int a = 0;
    static AtomicInteger a  = new AtomicInteger(0);

    @Override
    //每执行一次run方法a加10000次
    public void run() {
        //循环
        for (int i = 0; i < 10000; i++) {
            //a++;
            a.getAndIncrement();
        }
        System.out.println("循环结束了");
    }
}

public class Test02 {
    public static void main(String[] args) throws InterruptedException {
        //创建线程
        CCC c = new CCC();
        c.start();
        
        //创建线程
        CCC c2 = new CCC();
        c2.start();
        
        //main线程睡觉
        Thread.sleep(2000);
        //打印a变量
        System.out.println(CCC.a);

    }
}

        The working mechanism of the AtomicInteger class-CAS mechanism: that is, make a judgment when assigning, compare the obtained value with the value of the current variable, if the same, complete the assignment, otherwise re-assign

             

Guess you like

Origin blog.csdn.net/weixin_43267344/article/details/108093852