java study notes: volatile memory to solve the visibility problem

 

1, Java Memory Model

        java memory model specifies that all variables are stored in the main memory. Each thread also has its own working memory, working memory stored in the thread to be used by the thread variables (these variables are copies come from main memory). Thread all operations on variables (reading assignment) must be in working memory. Between different threads can not directly access the working memory of the other variables, the variable value passed between threads are required to complete the main memory.

2, Java in visibility

        For visibility, Java provides the volatile keyword to ensure visibility. When a shared variable is declared volatile, it will ensure that the modified values ​​will be updated immediately to the main memory, when there are other threads need to read, it will read the new value to memory. The ordinary share variables can not guarantee the visibility, because after a normal shared variables are modified, and when is written to main memory is uncertain when the other threads to read at this time may still be the original value of the old memory, so We can not guarantee visibility. In addition, synchronized and Lock can also guarantee visibility, synchronized and Lock ensures that only one thread acquires the lock and then synchronize code and to modify variables will be flushed to main memory of them before releasing the lock. So it can ensure visibility.

3, volatile keyword

       Java provides a weaker synchronization mechanism, namely volatile variable used to ensure that the update notification variables to other threads. volatile can be seen as a lightweight lock, and lock but it is a little different: a: For multi-threaded, not a mutually exclusive relationship; b: not guarantee the "atomic operations" variable state.

public class MyTest {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        new Thread(myRunnable).start();
        while (true){
                if (myRunnable.getFlag()) {
                    System.out.println("进来了");
                    break;
            }

        }
    }
}

class MyRunnable implements Runnable{
    private volatile boolean flag;
    @Override
    public void run() {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag=true;
        System.out.println("子线程修改了flag的值"+getFlag());
    }
    public boolean getFlag() {
        return flag;
    }
}

4, CAS algorithm

       CAS (Compare-And-Swap) is a hardware support for concurrent processors for multiprocessor designed to operate in a special instructions for managing concurrent access to shared data. CAS is a non-blocking lock-free algorithms. CAS includes three operands: a: the need to read and write memory value V; b: comparing the value of A; c: the proposed new value written B. If and only if the value is equal to V A, CAS B with a new value by updating the value of V atomic manner, it will not perform any operation.
      In simple terms, there are three operands CAS, to read the memory values V, the expected value of the old A, to be modified a new value B. If and only if the value of the expected value V A and the same memory, the memory value V modified as B, otherwise V. This is an optimistic locking of thinking, I believe it before it changes, no other threads to modify it.

5, atomicity problem

    Must have the atomicity in a transactional database, it does to all operations performed on the data change, or all is not executed. At this time, the atoms of the same concept. You can look at the atomic issue i ++.

//i++的操作实际上分为三个步骤”读-改-写”。
int i = 10;
i = i++; //10
//i++,实际上执行了下面三步:
int temp = i;
i = i + 1;
i = temp;
//只有这三步同时执行成功或失败,就是一个原子操作。

      Java.util.concurrent.atomic under this package, there are many variables for us to use the atom. After JDK1.5 provides some atomic variables for us to achieve a CAS algorithms use these atomic variables, we can solve this problem 

public class MyTest {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        for (int i = 0; i < 10; i++) {
            new Thread(myRunnable).start();
        }
        //我们采用同步来解决,可以,但是比较耗费性能
        //现在有一种这个CAS 算法可以解决原子性问题
        // CSA 比较并交换  是一种硬件对并发访问的支持
    }
}

class MyRunnable implements Runnable {
    //int i = 0;//普通变量
    AtomicInteger i = new AtomicInteger(); //原子变量


    public int getI() {
        return i.getAndIncrement();
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "====" + getI());
        }
    }
}

 

Published 24 original articles · won praise 11 · views 2048

Guess you like

Origin blog.csdn.net/weixin_43791069/article/details/86696065