Concurrent Programming - visibility, order, atomicity

All along, as cpu, memory, I / O there is a huge difference in speed, cpu> Memory> I / O. In order to balance the difference between these three, computer architecture, operating systems, compilers have made a great contribution, mainly reflected in:

1. Increase the cpu cache to balance and memory speed difference

2. The compiler optimization instruction execution order, so that the cache can be more rational use of

3. The increase in the operating system processes, threads, a time-division multiplexing cpu, cpu and then in balancing speed of I / O

Above optimization does increase cpu usage, improves the performance of the overall program, but also to our concurrent program caused some problems

1. cpu cache visibility problems caused by

In the single-core time, only one cpu and a cpu cache, different threads correspond to the same cache, visibility is not an issue. In the multi-core era, and every single cpu has its own cache, the operation of the different threads may be different cache. For example, thread A cpu1 cache operation, but the operation of the thread B is cpu2 cache, it is clear that at this time the operation of the thread variable v A, B for the thread is not visible

2. compiler optimization problems caused by ordering

In order to optimize the performance of compilers, sometimes changing the order of the statement, it will not only be more rational use cpu cache, while reducing unnecessary cpu pause. Then optimizing compiler can only guarantee the same serial semantics, we can not guarantee a consistent multi-threaded semantics. Create a singleton object in java classic example is the use of double checking locks.

public class Singleton {
  static Singleton instance;
  static Singleton getInstance(){
    if (instance == null) {
      synchronized(Singleton.class) {
        if (instance == null)
          instance = new Singleton();
        }
    }
    return instance;
  }
}

The problem in the new operator, the new operator is optimized, the order of execution of instructions to:

1. Allocate a memory M

2. The address M is assigned to instance variables

3. On the instance variables initialized memory M

A thread of execution, it is assumed that I getInstance method, after executing the instruction 2, B thread starts execution, the first time found that a B instance == null is false, return directly instance instance, however, at this time has not been initialized yet instance instance, this time B-threaded access instance member variables could trigger a null pointer exception

3. Thread switching problems caused by atomic

线程的切换是由操作系统来处理的,而操作系统走切换是能够发生在任何一条cpu执行完成的。而很多高级语言的一条语句对应cpu指令,count++这个操作则需要三条指令

  • 指令1:将count从内存load到cpu寄存器中
  • 指令2:将寄存器中的count进行+1
  • 指令3:将count写入内存

当线程A执行完指令1后,切换到线程B则发生原子性问题

 

     

Guess you like

Origin www.cnblogs.com/hello---word/p/10989801.html