java thread safety problem

Multi-threading is unsafe, mainly because of the cpu allocation mechanism, whoever gets the cpu can execute it, thus causing thread insecurity.

Now summarize the methods for judging whether thread safety is safe:

1. Clarify which codes are multi-threaded running code,
2. Clarify shared data
3. Clarify which statements in multi-threaded running code are operating shared data.

Through the above three points, write a piece of code,

package com.niuli.develop;

public class Test {
    public static void main (String [] args) {
        Cus c = new Cus();
        new Thread(c).start();
        new Thread(c).start();
    }
}

class Bank{
    private int sum = 0;
    public void add(int n) {
        sum = sum + n;
        System.out.println("sum= "+sum);
    }
}

class Cus implements Runnable{
    Bank b = new Bank();
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            b.add(100);
        }
    }
}

Very simple example, the
first step is to find the code that runs in multiple threads

也就是run方法里面的代码
for (int i = 0; i < 3; i++) {
            b.add(100);
        }
        另外这里用到了Add方法,所以add也算
 public void add(int n) {
        sum = sum + n;
        System.out.println("sum= "+sum);
    }

The second step is to find the shared data

Bank b = new Bank();
private int sum = 0;

The third step is to clarify the shared data used by multiple threads.
First of all, for data b, this shared variable is used in one statement, so there will be no thread insecurity, but for sum, there are two statements used, so there will be thread safety question,

Workaround: Use synchronized code blocks

Object obj = new Object();
    public void add(int n) {
        synchronized (obj) {
            sum = sum + n;
            System.out.println("sum= "+sum);
        }
    }

Or: Synchronized function

public synchronized void add(int n) {
            sum = sum + n;
            System.out.println("sum= "+sum);
    }

The above is the thread-safe solution. Although the synchronization mechanism is a ranger, it brings a certain performance loss. Therefore, perform synchronization on the part that operates the shared data to minimize this loss.

Replenish:

If the synchronization function is static, the lock used must be the bytecode file object of the class where it is located, that is, the class name. There may be objects of object, so the lock must be used on an object before static loading.

There are several principles:
Program order rule: Within a thread, the execution of code will be in the order in which the program is written
Monitor lock principle: The unlock operation on the same variable occurs first before the subsequent lock operation.
Volatile variable rules: write to a volatile The operation occurs first before the subsequent read operation.
Thread startup principle: Thread's start() occurs first in all actions in the thread.
Thread termination principle: All actions in the thread occur first in the thread termination detection.
Thread interruption principle: call interrupt on the thread () First occurs when the interrupted code detects whether there is an interrupt.
Object termination principle: The initialization operation of an object occurs first in the finalize() method.
Transitivity: A occurs first in B, B first occurs in C, then A occurs first in C

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325693974&siteId=291194637