Concurrent Programming (6): Thread Safety

  What is a thread-safe class?

  When a class is accessed by multiple threads, the class behaves correctly regardless of how the runtime environment is scheduled or how the processes will alternate, and no additional synchronization or coordination is required in the calling code. Then the class is said to be thread safe

 

  What are the characteristics of thread safety?

  Atomicity: Provides mutually exclusive access, only one thread can operate on it at a time

  Visibility: A thread's changes to main memory can be observed by other threads in time

  Orderliness: A thread observes the execution order of instructions of other threads. Due to the existence of instruction reordering, the observation results are generally disordered and out of order.

 

  atomicity

  The means of ensuring atomicity usually include the following

  When synchronization is required, perhaps the first thing we think of is synchronized, but when the competition is particularly fierce, synchronized may not be a good choice. There are several ways to use synchronized.

  Regarding atomic, we have an example application in the previous blog. We will give a special explanation on the use of Lock in the following blog. Let's take a brief look at the synchronized demo.

  synchronized-demo1 (modified method)

@Slf4j
public class SynchronizedExample1 {

    // modify a code block 
    public  void test1( int j) {
         synchronized ( this ) {
             for ( int i = 0; i < 10; i++ ) {
                log.info("test1-{}-{}", j,i);
            }
        }
    }

    // modify a method 
    public  synchronized  void test2( int j) {
         for ( int i = 0; i < 10; i++ ) {
            log.info("test2-{}-{}", j,i);
        }
    }

    public static void main(String[] args) {
        SynchronizedExample1 example1 = new SynchronizedExample1();
        SynchronizedExample1 example2 = new SynchronizedExample1();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(()->{
            example1.test2(1);
        });

        executorService.execute(()->{
            example2.test2(2);
        });

    }

}

 

  synchronized-demo2 (modified class)

@Slf4j
public class SynchronizedExample2 {

    // modify a class 
    public  static  void test1( int j) {
         synchronized (SynchronizedExample2. class ) {
             for ( int i = 0; i < 10; i++ ) {
                log.info("test1-{}-{}", j,i);
            }
        }
    }

    // modify a static method 
    public  static  synchronized  void test2( int j) {
         for ( int i = 0; i < 10; i++ ) {
            log.info("test2-{}-{}", j,i);
        }
    }

    public static void main(String[] args) {
        SynchronizedExample2 example1 = new SynchronizedExample2();
        SynchronizedExample2 example2 = new SynchronizedExample2();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(()->{
            example1.test1(1);
        });

        executorService.execute(()->{
            example2.test1(2);
        });

    }

}

 

  visibility

  Reasons why shared variables are not visible between threads

  Usually we have two ways to ensure visibility:

  a、synchronized

  There are two rules about synchronization in the java memory model

  1. Before the thread is unlocked, the latest value of the shared variable must be refreshed to the main memory

  2. When the thread locks, the value of the shared variable in the working memory will be cleared, so the latest value needs to be re-read from the main memory when using the shared variable (locking and unlocking must be the same lock)

 

  b、volatile

  volatile achieves visibility by adding memory barriers and disabling reordering optimizations

  a. When a volatile variable is written, a store barrier instruction will be added after the write operation to refresh the shared variable value in the local memory to the main memory

  b. When a volatile variable is read, a load barrier instruction will be added before the read operation to read the shared variable from the main memory

 

  volatile writes:

 

  volatile reads:

 

  orderliness

  In the java memory model, the compiler and processor are allowed to reorder instructions. The reordering process will not affect the execution of single-threaded programs, but will affect the correctness of multi-threaded concurrent execution. The ordering can rely on volatile, synchronized , Lock to guarantee.

  When it comes to orderliness, we can think of a very important principle in JMM (java memory model) - the happens-before principle:

  a. Program order rule: In a thread, according to the code order, the operation written in front occurs first before the operation written in the back

  b. Locking operation: an unLock operation occurs first before a subsequent lock operation for the same lock

  c, volatile variable rule: the write operation to a variable occurs first before the read operation of the latter variable

  d. Delivery rule: If operation A occurs first in operation B, and operation B occurs in operation C first, it can be concluded that operation A occurs first in operation C

  e. Thread startup rules: The start() method of the Thread object occurs first for every action of this thread

  f. Thread interrupt rules: The call to the thread interrupt() method occurs first when the code of the interrupted thread detects the occurrence of the interrupt event

  g. Thread termination rules: All operations in the thread occur first in the thread termination detection. It may be detected that the thread has terminated execution by the end of the Thread.join() method and the return value of Thread.isAlive().

  h. Object finalization rules: the initialization of an object occurs first at the beginning of its finalize() (GC calls this method before recycling the object) method

 

  If the execution order of the two operations cannot be inferred from the happens-before principle, the ordering cannot be guaranteed, and the virtual machine can reorder them at will.

 

 

 

 

  

Guess you like

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