Basic knowledge of Java thread synchronization in several ways

. Leads to a question:
In a multithreaded program, a plurality of threads to seize a resource will appear, this time may cause a conflict, that is, one thread may save resources have not had time to change, to change another thread it has started. It may result in inconsistent data. Therefore, the introduction of multi-thread synchronization, which means that multiple threads can only make changes to a shared resource, other threads can not modify the data.

Genlock:
In order to ensure that each thread can perform atomic operations normal, Java introduces a thread synchronization mechanism.
Synchronization Listener object / genlock / sync listener / mutex:
synchronized lock object is just a concept, it is conceivable as objects the mark of a lock.
the Java program to run using any object as a synchronization listener objects, but in general, we put together the resources of the current concurrent access as synchronization listeners object.
Note: at any time, at most one thread can own synchronization lock, who took proceeds to block the lock, the other outer thread can wait.

Second Solution:
① synchronized block

class Apple implements Runnable{
    private  int num=100;
    @Override
    public void run() {
        for (int i = 0;i<100;i++){
            synchronized (this) {
                if (num > 0) {
                    System.out.println(Thread.currentThread().getName() + "吃了第" + num + "个苹果");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    num--;
                }
            }
        }
    }
}
public class SynchronizedBlockDemo {
    public static void main(String[] args) {
        Apple apple = new Apple();
        new Thread(apple, "A").start();
        new Thread(apple, "B").start();
        new Thread(apple, "C").start();
    }
}

Method ② Synchronous
synchronization method: synchronized using a modified method, called the synchronization method, to ensure that when a thread of execution of the method A, the other thread can wait out the method.
Synchronized public void the doWork () {
/// the TODO
}
genlock who:
for non-static method, synchronization lock is this.
for the static method, we use bytecode object of the current class method where (Apple2.class).

class Apple1 implements Runnable {
    private int num = 100;
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            eat();
        }
    }
   synchronized private void eat(){
        if (num > 0) {
            System.out.println(Thread.currentThread().getName() + "吃了第" + num + "个苹果");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            num--;
        }
    }
}

public class SynchronizedMethodDemo {
    public static void main(String[] args) {
        Apple1 apple = new Apple1();
        new Thread(apple, "A").start();
        new Thread(apple, "B").start();
        new Thread(apple, "C").start();
    }
}

Note: Do not use a modified run synchronized method, after modification, one thread is finished on all of the functions performed by multiple threads appear like a serial.
Solution: The code defines synchronous operation is required in a new way, and the modified method uses synchronized, then you can call this new method in the run method.

synchronized good or bad:
benefits: ensures synchronous operation of multi-threaded concurrent access, to avoid security problems thread.
Cons: using synchronized methods / performance code block to do some low ratio.
Recommendation: minimize the synchronized scope.

③ double-checked locking (singleton - lazy man)
can use the "double check locking" way to achieve, you can achieve both thread-safe, but also to the performance is not greatly affected. So what is the "double check locking" mechanism?
  The so-called "double-checked locking" mechanism, means: not always enter the getInstance methods need to be synchronized, but the first is not synchronized, into the method, first check whether there are instances, if there were only following sync blocks, this is the first re-examined after entering the sync block, check again whether there instance, if there is, it creates an instance in the case of synchronization, which is the second re-examination. Thus, it is only once the synchronization, thereby reducing the time wasted is determined a plurality of times in the synchronous case.
  "Double check locking" implementation mechanism will use the keyword volatile, it means: modified value is volatile variable will not be thread-local cache, read and write all the variables are directly manipulated shared memory, thereby ensuring that multiple threads can correctly handle the variable.
Note: java1.4 and previous versions, many of JVM for volatile issue to achieve a keyword, it will lead to "double check locking" of failure, so the "double-checked locking" mechanism can only be used only in java5 and above version.
Note: Due to the volatile keyword may block out some of the necessary virtual machine code optimization, operational efficiency is not so high. It is generally recommended that no special needs, do not use. In other words, although you can use the "double check locking" mechanisms to achieve thread-safe singleton, but does not recommend the use of a large number can be selected according to the situation.

public class ThreadUtils {
    private ThreadUtils() {
    }
    private static volatile ThreadUtils instance = null;

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

④ synchronization lock (Lock):
Lock mechanism provides broader than the locking operation and synchronized methods synchronized code block, the block synchronization code / synchronization method having the features Lock has, in addition to more powerful, object-oriented reflected.

class Apple2 implements Runnable {
    private int num = 100;
    private final Lock lock = new ReentrantLock();//创建一个锁对象

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            eat();
        }
    }

    private void eat() {
        //进入方法进加锁
        lock.lock();
        try {
            if (num > 0) {
                System.out.println(Thread.currentThread().getName() + "吃了第" + num + "个苹果");
                Thread.sleep(100);
            }
            num--;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();//释放锁
        }
    }
}

public class LockDemo {
    public static void main(String[] args) {
        Apple2 apple = new Apple2();
        new Thread(apple, "A").start();
        new Thread(apple, "B").start();
        new Thread(apple, "C").start();
    }
}

Interview questions:
①volatile synchronized with the difference between

A: 1) volatile nature is telling jvm current value of the variable in a register is uncertain, needs to be read from main memory, synchronized current variable is locked, only the current thread can access the variable choke means other threads.
2) can be used only in volatile variable level, synchronized variables can be used in process.
. 3) can be achieved only modify the visibility volatile variables, and modify the synchronized variables can ensure visibility and atomicity.
4) will not cause obstruction volatile thread, and synchronized might cause obstruction thread.

What difference ② synchronization method and synchronized block is?
A is a synchronous code block, one is to synchronize the entire process, under normal circumstances, the synchronization of the greater range, performance is also worse.

? Difference ③synchronized and lock the
A: 1.synchronized is implemented on the JVM level, not only can monitor the synchronized locking through a number of monitoring tools, and an exception when code is executed, JVM will automatically release the lock,
but is not using the Lock, lock is achieved through code, to ensure that the lock will be released, it must be unLock () put in finally {}
2. in the
resource competition is not very intense
in the case, Synchronized better performance than ReetrantLock,
but resources competition is fierce in the case, Synchronized performance will fall a few times, but ReetrantLock performance can be maintained normal;

Published 99 original articles · won praise 2 · Views 2617

Guess you like

Origin blog.csdn.net/weixin_41588751/article/details/105211453