In addition Synchronized keyword, what can guarantee thread safety?

In addition Synchronized keyword, what can guarantee thread safety?

    Daily use Java development, multi-threaded development, generally with Synchronized thread-safe, to prevent errors and exceptions occur concurrently, so
in addition to Synchronized keyword, what can guarantee thread-safe?

What is thread safe?

    Before looking at how we can ensure the security thread, we first define what is thread-safe. Wikipedia is so defined:

Thread safety is a term used in programming, referring to a function, when the library is called in a multithreaded environment, able to correctly handle multiple threads between the
shared variables, make the program function properly completed.

As I understand it, in a multithreaded environment program functions properly completed, it means no matter under single-threaded or multithreaded environment, this program runs to fully
realize the need for program design features, there is no BUG. Therefore, in order not BUG, we must ensure that single-threaded or multithreaded environment code that runs
security.

Without considering the security thread okay?

    Some would say, do not multi-threaded okay, I only write single-threaded code is not on it, they would not have a single-threaded thread safety problem, right. If only a single
thread, then visit a Web page will appear in a scene similar to queue up for tickets, a request returns to continue processing the next request, the efficiency is very low.
Multithreading, you can take advantage of multicore CPU resources to improve performance, especially in the presence compute-intensive, IO-intensive tasks.
    So open multi-process (process), a process corresponding to a thread okay? In this case, Java programming language to run on each access to a
request on the need to open a new JVM, again class load and so on, including the JVM optimizations, caching, optimizing the advantages of warm-up like all gone .
    So just open a thread, a thread corresponding number of coroutines (coroutine) or micro-thread (fiber) okay? First Java language itself does not provide native
born coroutine implementation, followed by even realized, the only single-threaded or not take advantage of multicore CPU resources, will achieve the performance bottleneck.
    In the final analysis for performance, the use of multi-line Cheng Youyi, the price is for a shared mutable state and in terms of resources, as long as the conditions of competition (race exist
condition), thread-safety issues must be taken into account when developing code.

It is not thread-safe under what circumstances?

    To avoid thread-safe, we must first understand the problem appears not thread-safe under what circumstances. A variable is used only in the thread, this
case needs to consider thread safety problem? No, only the variables required shared among multiple threads access operations, we need to consider thread
safety issues. All threads share the variables you need to consider? No, if a variable is initialized after no change in that variable is immutable state, I
have no need to consider. So, when an access to a shared variable objects to appear thread-safety problem exists only between the threads.

How to ensure thread safety?

Do not share

    As previously mentioned, there will be security thread only needs to operate the variable objects sharing, as long as it is not a shared object can not guarantee thread-
safe yet. To ensure that the method of the object itself or its reference will not be shared out, such as local variables are not exposed to certainly, can also use the
ThreadLocal save and passing objects.

Immutable (the immutable)

    If you must share, then the object is immutable state, but also to ensure thread safety. Under what circumstances does the object is immutable? After the object constructor
has attributes will not change is immutable. In Case of A,

public class A {
    private int fieldA;
    private int[] fieldB;
    
    public A(C c) {
        c.setD(new D());
        // 初始化
    }

    public void setFieldA(int a) {
        fieldA = a;
    }

    public int[] getFieldB() {
        return fieldB;
    }

    private void updateA() {
        //修改内部状态
    }

    class D {
        public void updateD() {
            updateA();
        }
    }
}

First, we need to attribute becomes final, to ensure that other properties do not fluctuate after the constructor initializes prevent property status will be changed.

public class A {
    private final int fieldA;
    private final int[] fieldB;
    
    public A(C c) {
        c.setD(new D());
        // 初始化
    }

    public int[] getFieldB() {
        return fieldB;
    }

    private void updateA() {
        //修改内部状态
    }

    class D {
        public void updateD() {
            updateA();
        }
    }
}

Second, to prevent the internal reference variable objects exposed to.

public class A {
    // 置为final状态
    private final int fieldA;
    private final int[] fieldB;
    
    public A(C c) {
        c.setD(new D());
        // 初始化
    }

    public int[] getFieldB() {
        if (fieldB == null) {
            return null;
        }
        // 防止引用暴露,外部可以修改fieldB状态
        return Arrays.copyOf(fieldB, fieldB.length);
    }

    private void updateA() {
        //修改内部状态
    }

    class D {
        public void updateD() {
            updateA();
        }
    }
}

To prevent the last constructor escape this class A (this Escape), preventing the constructor has not been initialized yet, other threads may be utilized to escape
this internal method call.

public class A {
    // 置为final状态
    private final int fieldA;
    private final int[] fieldB;
    
    public A(C c) {
        // updateD方法可能在c被其他线程调用,间接调用updateA方法,修改了Class A实例的状态
        c.setD(new D());
        // 初始化
    }

    public int[] getFieldB() {
        if (fieldB == null) {
            return null;
        }
        // 防止引用暴露,外部可以修改fieldB状态
        return Arrays.copyOf(fieldB, fieldB.length);
    }

    private void updateA() {
        //修改内部状态
    }

    class D {
        // 去除updateD方法
    }
}

Single-threaded modification

    And shared object must be variable, if only one thread is modified, the other thread just read, you only need to add the volatile state of the object whose properties
key modification to ensure visibility of memory, other threads can read the latest state of the object, so it can guarantee thread safety.

The object properties to modify the type of security thread

public class A {
    private Map<Integer, B> fieldB;

    public A() {
        fieldB = new HashMap<>();
    }
    
    public B getB(Integer key) {
        return fieldB.get(key);
    }

    public B addB(Integer key, B value) {
        B b = fieldB.get(key);
        if (b == null) {
            fieldB.put(key, value);
        }
        return b;
    }
}

The security thread entrusted to the properties of an object, the properties of the object thread-safe guarantee

public class A {
    private final Map<Integer, B> fieldB;

    public A() {
        fieldB = new ConcurrentHashMap<>();
    }
    
    public B getB(Integer key) {
        return fieldB.get(key);
    }

    public B addB(Integer key, B value) {
        return fieldB.putIfAbsent(key, value);
    }
}

Use the synchronized keyword

    For shared variable object, all the attributes required to modify the read state are synchronized with the modified

public class A {
    private B fieldB;
    
    public synchronized B getB() {
        return fieldB;
    }

    public synchronized void updateB() {
        // 其他操作
        fieldB.update();
        // 其他操作
    }
}

You can be optimized using an internal private object as a lock object is locked to avoid the overall process

public class A {
    private B fieldB;
    private final Object lock = new Object();
    
    public synchronized B getB() {
        return fieldB;
    }

    public void updateB() {
        // 其他操作
        synchronized (lock) {
            fieldB.update();
        }
        // 其他操作
    }
}

Guess you like

Origin www.cnblogs.com/yeyu456/p/12016324.html