Multi-threaded security problem-solving display lock Lock

[1] Display lock and implicit lock

Prior to Java 5.0, the only mechanisms that could be used to coordinate access to shared objects were synchronized and volatile. Some new mechanisms have been added since Java 5.0, but it is not a way to replace the built-in locks, but as an optional advanced feature when the built-in locks are not applicable. That is, the display lock (synchronous lock) - Lock.

Users solve three ways of multi-thread security problems:

  • synchronized synchronization code block;
  • synchronized synchronization method;
  • 同步锁Lock.

where synchronized is called an implicit lock, and Lock is called a display lock.

何是display lock?

needs to be locked by the lock() method, and the lock must be released by the unlock() method.   Usually in order to guarantee the release of the lock, put the unlock() method in finally.

In the java.util.concurrent.locks package about lock and synchronization auxiliary classes are as follows:

这里写图片描述

[2] multi-threaded ticketing problem and Lock instance

first look at a multi-threaded ticketing problem :

public class TestLock {
    public static void main(String[] args){

        Ticket ticket = new Ticket();
        new Thread(ticket,"1号窗").start();new Thread(ticket,"2nd window").start();new Thread(ticket,"3rd window") .start();

    }
}class Ticket implements  Runnable{

    private  int ticket = 100;

    @Override
    public void run() {

        while (true){
            try {
                //Enlarge multithreading problemThread.sleep(200);
                if(ticket>0){
                    System.out.println(Thread.currentThread().getName()+" Complete ticket sales, the remaining ticket is: "+--ticket);
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

test results are shown below:

这里写图片描述

There may be classmates who will say that Volatile is viewed from memory visibility, using Volatile, which allows shared data to maintain memory visibility across multiple threads, and Ability to notify other threads of data changes.

Then there is a problem. As the blog post describes, volatile is not mutually exclusive and does not support variable atomic operations.

As shown below:

public class TestLock {
    public static void main(String[] args){

        Ticket ticket = new Ticket();
        new Thread(ticket,"1号窗").start();new Thread(ticket,"Window 2").start();new Thread(ticket,"3 Number window ").start();

    }
}class Ticket implements  Runnable{
    //Use volatile decoration 
    private volatile int ticket = 100;

    @Override
    public void run() {

        while (true){
            try {
                // to enlarge multi-threading problemThread.sleep(200);
                if(ticket>0){
                    System.out.println(Thread.currentThread().getName()+" Complete ticket sales, the remaining ticket is: "+--ticket);
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

Test as shown below:

这里写图片描述

不光数据不待, even negative numbers!

这里写图片描述

synchronized can of course solve this problem, but do not use synchronized, use lock.

Modify the code as follows:

public class TestLock {
    public static void main(String[] args){

        Ticket ticket = new Ticket();
        new Thread(ticket,"1号窗").start();new Thread(ticket,"2nd window").start();new Thread(ticket,"3 Number window ").start();

    }
}
Class Ticket implements Runnable{private volatile int ticket = 100;

    private Lock lock = new ReentrantLock();

    @Override
    public void run() {

        while (true){
            try {
                lock.lock();
                //Enlarge multithreading problemThread.sleep(200);
                if(ticket>0){
                    System.out.println(Thread.currentThread().getName()+" Complete ticket sales, the remaining ticket is: "+--ticket);
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                // Guarantee lock release 
                lock.unlock();
            }
        }

    }
}

again test, the result is normal!

这里写图片描述