Multithreading --volatile

  Before explaining the volatile keyword, first talk java rearrangement instruction execution order code.

  Rearranging instructions:

public void sum(){
	int x = 1;
	int y = 2;
int x = x + 1;
int sum = x + y; }

  Order code, when executed give give assignments x y assignment, then perform x = x + 1; final summation.

  Since x = x + 1 and the sum = x + y is not write an instruction rearrangement, but x = 1 and y = 2 are not mutually exclusive; optimized for performance considerations (directly after the assignment x x can save operation time x reacquire memory address), instructions may be rearranged to the maximum y-x assigned assignment again.

  Rearrangement instruction does not affect the results of an optimization method.

  Sequential code execution: When volatile variables before and after the single-threaded code compiler optimization is not rearranged, the execution code sequence. Concurrency, multi-threaded, sequential operations to shared variables. Because competition is multi-threaded execution, execution order is random, it is likely to break the atomic operating variables while operating volatile variables.

  1.volatlie not guarantee atomicity operation variables

  The basic data types for int type variables: multithreading operation in the heap memory is read from the thread stack to variable values, variable values ​​operates on the thread stack, then the variable value is written back to the heap memory. Breaking the atom refers to the two threads are then written back to the middle of the process of heap memory heap memory to read data from is interrupted, causing the value of the variable and unpredictable. For example: remove x = 1; x ++ thread first operation, the second thread x-- operation, the final result is likely to be performed may also be 2 0.

public class VolatileNotAtomic {
	private static volatile long count = 0L;
	private static final int NUMBER = 10000;
	
	public static void main(String[] args) {
		Thread substractThread = new SubstractThread();
		substractThread.start();
		
		for (int i = 0; i < NUMBER; i++) {
			//synchronized(VolatileNotAtomic.class) {
				count++;
			//}
		}
		
		//等待线程结束
		while (substractThread.isAlive()) {}
		
		System.out.println("count : " + count);
	}
	
	private static class SubstractThread extends Thread {
		@Override
		public void run() {
			for (int i = 0; i < NUMBER; i++) {
				//synchronized (VolatileNotAtomic.class) {
					count--;
				//}
			}
		}
	}

}

  Execute this code, the results are not 0; volatile variables described operation is not atomic. To ensure atomicity operation, open to the synchronization code block comments.

  volatile memory semantics to ensure visibility only instruction rearrangement does not occur, the variable guaranteed. Here memory refers to main memory (heap memory) instead of working memory (stack memory). Get the value of the shared variable thread start reading the main memory is loaded into the working memory, reading and writing back thread are variable values ​​occur in the working memory, and main memory does not guarantee value of the synchronization, this time in the multi-threaded when the value of the variable will lead to inconsistency. After volitale modified with variable force variable value read from the main memory, to ensure the visibility of the main memory value.

  2. volatile variable itself ensure atomicity of write, read operation after a write operation; typical application scenarios: a Write Once Read Many

  Analysis The following procedure to achieve a single case double lock object to set forth a multi-volatile read-write applications.

  Examples of the sequence of objects:

  Parent static member and a static code block ==> parent class static method ==> sub static member and a static code block ==> subclass static method ==> ordinary members and the parent class ==> = parent class constructor => subclass members and ordinary methods ==> subclass Constructors

  First, the object will apply the heap memory space and perform the instantiation process upon instantiation.

  Dual single locking embodiment the subject as follows:

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

  Problems that the above code: when multiple threads of execution, if the thread 1 to perform a new Singleton (), but the object instantiation process is not complete, then the thread 2 will be acquired call getInsatnce unfinished instantiated objects (objects allocated memory can be accessed), lead to erroneous results.

  Solve the problem just before sinleton variables plus volatile keywords.

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

 

Guess you like

Origin www.cnblogs.com/beichenroot/p/11445042.html