volatile

introduce

Visibility problem
  • Make changes made by one thread to a shared variable visible to other threads in a timely manner.
  • According to the Happen Before and synchronization principles specified in the JMM:
    • Happens-before Each subsequent read to a volatile field.
    • Writes to volatile v are synchronized with subsequent reads to v by all other threads
What does volatile need to do to avoid visibility problems
  1. Disable caching;
  2. The access control for volatile variables is appended with ACC _VOLATILE
  3. Docs.oracle.com/javase/spec…
  4. Do not reorder volatile volatile instructions.

Thread safety

Critical regions and race conditions

  1. Race condition: In the critical area, the code that causes thread-safety problems.
  2. Critical area: The area where thread safety issues can occur in the case of multiple threads.

Shared resources

  • If a piece of code is thread-safe, it contains no race conditions. A race condition occurs only when multiple threads update a shared resource.
  • Variables that are not shared between threads when the stack is closed are thread-safe.
  • The local object reference itself is not shared, but the referenced object is stored in the shared heap. Objects created within a method are also thread-safe if they are only passed through the method and are not available to other threads.
public void someMethod(a){
    Localobject localobject = new Localobject();
    localobject.callMethod();
    method2(localobject);
}
public void method2(Localobject localobject{
	localobject.setValue("value");
}
Copy the code

Immutable object

Create immutable shared objects to ensure that they will not be modified when shared between threads, thus achieving thread safety. Once the instance is created, the value variable cannot be modified, which is immutability.

public class Demo{
    private int value = O;
    public Demo(int value){
    	this.value = value;
    }
    public int getValue(a){
    	return this.value; }}Copy the code

Atomic operation

Nature: Consistency of data

The definition of atomicity

  1. Variables affected by atomic operations remain consistent (cannot be changed or modified) within atomic operations.

Mechanism of the CAS

  1. Near-direct memory operations

Using Unsafe for atomicity

  1. Take the unsafe. GetIntVolatile
  2. change
  3. write
static{
    try{
        // The reflection technique gets the object
        Field theUnsafe = Unsafe.class. getDeclaredField( name: "theUnsafe");
        theUnsafe.setAccessible(true);
        unsafe = (Unsafe)theUnsafe.get(null) :// Using unsafe, address an attribute (the memory address of an object in memory)
        iOffset = unsafe.objectFieldPffset(LockDemo1.class.getDeclaredField(name: "i":))}catch(Exception ex) { ex.printStackTrace(); }}/ / optimization
public void add(a){
    int current; 
    //i++;
    current = unsafe.getIntVolatile( o: this, iOffset);
    unsafe.compareAndSwapInt( o: this.iOffset, current, i1: current + 1) :/ / CAS command
}
Copy the code
  • GetIntVolatile Note that volatile disables instruction reordering and caching
  • All are native modifications of native methods
    • Native non-Java methods, implemented using C.
  • Unsafe refers to the memory location of a variable based on its offset relative to the current object
  • Disadvantages: In the case of high concurrency, retry is performed continuously, resulting in resource consumption.

Use Atomic for atomicity

Principle: spin lock

// volatile int i = 0;
AtomicInteger i = new AtomicInteger(initialValue: 0);public void add(a) {
    i.incrementAndGet():// i++
}
Copy the code

Use LongAdder for atomicity

Since: JDK 1.8 +

  • Big data processing ideas >>> Divide and conquer
  • Each thread has a unique accumulator that can be taken out and added when it needs to be added. Retries (Atomic) or races (sync) are avoided.
  • Suitable for high writing and low reading scenarios

Several problems exist in CAS

ABA problem

  • What
    • Operations that should have failed did succeed, resulting in no way to reflect changes in the data.
  • Why
    • Thread 1 and thread 2 both initiate CAS requests for variable I. In the correct case, one of the threads should fail (let’s assume thread 2 fails).
    • But after thread 1 successfully executes, thread 3 executes before thread 2. I changed back to thread 2
    • Thread 2 says, “I” is still 1, I want to find it, so I change it to 2 again
  • How
    • Do not define data as simple primitive data types

How to avoid

  • Use the J.U.C class with the version number
  • It’s not just about numbers and results
  • Changes to the data are recorded by the version number
  • The version number comparison will be added when comparing

Atomic manipulation classes provided by the J.U.C package

thought

Divide and conquer

Count the number of clicks on an image

  • Multiple servers to separate statistics, separate records
  • The summary server summarizes all records


Copyright statement

  • Author: ** Liu Xi
  • This paper links: * * www.yuque.com/diamond/ndv…
  • Copyright Notice: ** All articles on this blog are licensed under a CC BY-SA 4.0 license unless otherwise stated. Reprint please indicate the source!
  • Release date: **2019-6-26 22:09:01