[Java multithreading] Lock lock method to solve thread safety problems

Lock (lock)

1. Starting from JDK 5.0 , Java provides a more powerful thread synchronization mechanism - synchronization is achieved by explicitly defining synchronization lock objects. Synchronization locks are implemented using Lock objects.

2. The java.util.concurrent.locks.Lock interface is a tool for controlling access to shared resources by multiple threads . The lock provides exclusive access to shared resources. Only one thread can lock the Lock object at a time, and the thread should obtain the Lock object before it starts to access the shared resource .

3. The ReentrantLock class implements Lock , which has the same concurrency and memory semantics as synchronized . In implementing thread-safe control, ReentrantLock is more commonly used , which can explicitly lock and release locks.

=========================================================================

Question: Create three windows to sell tickets, with a total of 100 tickets. as an example

Code with unresolved thread safety issues:

class Window implements Runnable {

    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            if (ticket > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":售票,票号为:" + ticket);
                ticket--;
            } else {
                break;
            }
        }
    }
}

public class LockTest {
    public static void main(String[] args) {
        Window w = new Window();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }

}

The above codes will result in heavy votes and wrong votes.

Next, we solve the thread safety problem through the Lock lock method

Lock (lock)

class A{
        private final ReentrantLock lock = new ReenTrantLock();
        public void m(){

            lock.lock();

            try{
                //保证线程安全的代码;
            }

            finally{

                lock.unlock();

            }
        }
    }

The code after using the Lock lock method to solve the thread safety problem is as follows:

class Window implements Runnable {

    private int ticket = 100;

    //1.实例化ReentrantLock
    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
            try {

                //2.调用锁定方法lock()
                lock.lock();
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":售票,票号为:" + ticket);
                    ticket--;
                } else {
                    break;
                }
            }finally {
                //3.调用解锁方法:unlock()
                lock.unlock();
            }
        }
    }
}

public class LockTest {
    public static void main(String[] args) {
        Window w = new Window();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }

}

==================================================== ===========================
Synchronized vs. Lock

1. Lock is an explicit lock (open and close the lock manually, don't forget to close the lock), synchronized is an implicit lock, and it is automatically released when it goes out of scope

2. Lock only has code block locks, synchronized has code block locks and method locks

3. Using the Lock lock, the JVM will spend less time scheduling threads and have better performance. And has better extensibility (provide more subclasses)

Order of preference:

Lock -> Synchronization code block (has entered the method body, allocated corresponding resources) -> Synchronization method (outside the method body)

thanks for watching! ! !

Guess you like

Origin blog.csdn.net/qq_64976935/article/details/128893834