Two, java multithreading thread-safe basis as much as summary and analysis

First, the security thread why there

1. When multiple threads share the same global variables or static variables when doing a write operation, the data may conflict that is thread safety problem occurs. But do not read data conflicts occur.

Second, code examples

1. Code

public class ThreadTrain implements Runnable {
    private int trainCount = 100;
    @Override
    public void run() {
        while (trainCount > 0) {
            try {
                Thread.sleep(500);
            } catch (Exception e) {

            }
            sale();
        }
    }
    public void sale() {
        if (trainCount > 0) {
            System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - trainCount + 1) + "张票");
            trainCount--;
        }
    }
    public static void main(String[] args) {
        ThreadTrain threadTrain = new ThreadTrain();
        Thread t1 = new Thread(threadTrain, "①号");
        Thread t2 = new Thread(threadTrain, "②号");
        t1.start();
        t2.start();
    }
}

2. Results

3. Analyze

One window and the window number two while selling tickets, some tickets will be repeated for sale , when the conclusions found that multiple threads share the same global member variable, do the data write operation may conflict occurs.

Third, thread-safe solution

1. synchronous or synchronized using the lock (lock), the data may conflict (thread safe issue) will occur between multiple threads, a thread can only make the current execution. After the completion of the implementation of the code to release the lock, so that after let other threads for execution. In this case we can solve the problem of insecurity thread.

2. Built using the synchronized keyword lock to achieve, synchronized keyword in two ways:

2.1. Modifications need to be synchronized method (method to access all state variables must be synchronized), then acts as a lock object as having synchronization method invocation

2.2 synchronized block and synchronized directly modified using methods that require synchronization are the same, but the lock granularity may be finer, and acts as a lock is not necessarily the this object, other objects may be, it is more flexible to use.

2.3 Each Java object can be used to achieve a synchronized lock, known as the built-in lock, the lock before the thread automatically get into the synchronized block, a block of code to perform normal exit or complete block of code will throw an exception freed exit lock, built-in lock for the mutex, that is, after thread a acquires a lock, thread B a blocked until the thread releases the lock, the thread B in order to obtain the same lock.

3. Code (synchronization method, other methods will be omitted)

public class ThreadTrain implements Runnable {
    private int trainCount = 100;
    @Override
    public void run() {
        while (trainCount > 0) {
            try {
                Thread.sleep(500);
            } catch (Exception e) {

            }
            sale();
        }
    }
    public synchronized void sale() {
        if (trainCount > 0) {
            System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - trainCount + 1) + "张票");
            trainCount--;
        }
    }
    public static void main(String[] args) {
        ThreadTrain threadTrain = new ThreadTrain();
        Thread t1 = new Thread(threadTrain, "①号");
        Thread t2 = new Thread(threadTrain, "②号");
        t1.start();
        t2.start();
    }
}

3.1. The results (normal result)

①号,出售第1张票
②号,出售第2张票
①号,出售第3张票
②号,出售第4张票
①号,出售第5张票
②号,出售第6张票
①号,出售第7张票

Four, ThreadLocal usage

1.ThreadLocal improve a thread local variable, to access a thread has its own local variables (each thread has one).

2. When using ThreadLocal variable maintenance, ThreadLocal provided for each thread using the variable independent variable copy, each thread can independently change their copy without affecting other threads corresponding copy.

3. Code

class Res {
    // 生成序列号共享变量
    public static Integer count = 0;
    public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
        protected Integer initialValue() {
            return 0;
        };
    };
    public Integer getNum() {
        int count = threadLocal.get() + 1;
        threadLocal.set(count);
        return count;
    }
}
public class ThreadLocaDemo2 extends Thread {
    private Res res;

    public ThreadLocaDemo2(Res res) {
        this.res = res;
    }
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName() + "---" + "i---" + i + "--num:" + res.getNum());
        }
    }
    public static void main(String[] args) {
        Res res = new Res();
        ThreadLocaDemo2 threadLocaDemo1 = new ThreadLocaDemo2(res);
        ThreadLocaDemo2 threadLocaDemo2 = new ThreadLocaDemo2(res);
        ThreadLocaDemo2 threadLocaDemo3 = new ThreadLocaDemo2(res);
        threadLocaDemo1.start();
        threadLocaDemo2.start();
        threadLocaDemo3.start();
    }
}

4. Results

Thread-0---i---0--num:1
Thread-0---i---1--num:2
Thread-0---i---2--num:3
Thread-2---i---0--num:1
Thread-2---i---1--num:2
Thread-2---i---2--num:3
Thread-1---i---0--num:1
Thread-1---i---1--num:2
Thread-1---i---2--num:3

Fifth, the end of the

1. Today, this stop here! ! !

Published 122 original articles · won praise 64 · views 50000 +

Guess you like

Origin blog.csdn.net/chenmingxu438521/article/details/103763169