Explain the use of Java multithreaded tryLock of method in detail

  • 2021-12-04 19:01:44
  • OfStack

The function of tryLock (long time, TimeUnit unit) is to obtain the lock if the lock is not held by another thread and the current thread is not interrupted in a given waiting time. The time-limited waiting of the lock object can be realized by this method.


package com.wkcto.lock.reentrant;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 *tryLock(long time, TimeUnit unit)  Basic use of 
 */
public class Test07 {
    static class TimeLock implements Runnable{
        private static ReentrantLock lock = new ReentrantLock();    // Defining a lock object 

        @Override
        public void run() {
            try {
                if ( lock.tryLock(3, TimeUnit.SECONDS) ){       // Get the lock back true
                    System.out.println(Thread.currentThread().getName() + " Acquisition of a lock , Perform time-consuming tasks ");
//                    Thread.sleep(4000);         // Hypothesis Thread-0 Threads hold locks first , Requirements for completing tasks 4 Seconds ,Thread-1 Thread attempting to acquire lock ,Thread-1 Thread in 3 If you don't get the lock within seconds, ,Thread-1 The thread will give up 
                    Thread.sleep(2000);          // Hypothesis Thread-0 Threads hold locks first , Requirements for completing tasks 2 Seconds ,Thread-1 Thread attempting to acquire lock ,Thread-1 Thread meeting 1 Direct attempt , In what it agreed to try 3 The lock object can be obtained within seconds 
                }else {         // No lock acquired 
                    System.out.println(Thread.currentThread().getName() + " No lock acquired ");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (lock.isHeldByCurrentThread()){
                    lock.unlock();
                }
            }
        }
    }

    public static void main(String[] args) {
        TimeLock timeLock = new TimeLock();

        Thread t1 = new Thread(timeLock);
        Thread t2 = new Thread(timeLock);
        t1.start();
        t2.start();
    }
}

tryLock () only locks the lock that is not held by other threads when calling. If the lock object is held by other threads when calling the method, it will be abandoned, and the calling method will try to get it. If the lock is not occupied by other threads, it will return true to indicate that the lock is successful; If the lock is occupied by another thread, it returns false without waiting.


package com.wkcto.lock.reentrant;

import java.util.concurrent.locks.ReentrantLock;

/**
 *tryLock()
 *   The lock is acquired only if the lock object is not held by another thread 
 */
public class Test08 {
    static class Service{
        private ReentrantLock lock = new ReentrantLock();
        public void serviceMethod(){
            try {
                if (lock.tryLock()){
                    System.out.println(Thread.currentThread().getName() + " Get a lock ");
                    Thread.sleep(3000);     // Simulate the duration of the task 
                }else {
                    System.out.println(Thread.currentThread().getName() + " No lock obtained ");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (lock.isHeldByCurrentThread()){
                    lock.unlock();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();
        Runnable r = new Runnable() {
            @Override
            public void run() {
                service.serviceMethod();
            }
        };

        Thread t1 = new Thread(r);
        t1.start();
        Thread.sleep(50);       // Sleep 50 Milliseconds , Ensure t1 Thread locking 
        Thread t2 = new Thread(r);
        t2.start();
    }
}

package com.wkcto.lock.reentrant;

import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;

/**
 *  Use tryLock() Deadlock can be avoided 
 */
public class Test09 {
    static class  IntLock implements Runnable{
        private static ReentrantLock lock1 = new ReentrantLock();
        private static ReentrantLock lock2 = new ReentrantLock();
        private int lockNum;        // Used to control the order of locks 

        public IntLock(int lockNum) {
            this.lockNum = lockNum;
        }

        @Override
        public void run() {
            if ( lockNum % 2 == 0 ){    // Even number first lock 1, Re-lock 2
                while (true){
                    try {
                        if (lock1.tryLock()){
                            System.out.println(Thread.currentThread().getName() + " Acquisition of a lock 1,  I also want to get the lock 2");
                            Thread.sleep(new Random().nextInt(100));

                            try {
                                if (lock2.tryLock()){
                                    System.out.println(Thread.currentThread().getName() + " Acquire locks at the same time 1 And lock 2 ---- Complete the task ");
                                    return;         // End run() Method execution , That is, the current thread ends 
                                }
                            } finally {
                                if (lock2.isHeldByCurrentThread()){
                                    lock2.unlock();
                                }
                            }
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        if (lock1.isHeldByCurrentThread()){
                            lock1.unlock();
                        }
                    }
                }
            }else {     // Odd numbers are locked first 2, Re-lock 1
                while (true){
                    try {
                        if (lock2.tryLock()){
                            System.out.println(Thread.currentThread().getName() + " Acquisition of a lock 2,  I also want to get the lock 1");
                            Thread.sleep(new Random().nextInt(100));

                            try {
                                if (lock1.tryLock()){
                                    System.out.println(Thread.currentThread().getName() + " Acquire locks at the same time 1 And lock 2 ---- Complete the task ");
                                    return;         // End run() Method execution , That is, the current thread ends 
                                }
                            } finally {
                                if (lock1.isHeldByCurrentThread()){
                                    lock1.unlock();
                                }
                            }
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        if (lock2.isHeldByCurrentThread()){
                            lock2.unlock();
                        }
                    }
                }
            }
        }
    }
    public static void main(String[] args) {
        IntLock intLock1 = new IntLock(11);
        IntLock intLock2 = new IntLock(22);
        Thread t1 = new Thread(intLock1);
        Thread t2 = new Thread(intLock2);
        t1.start();
        t2.start();
        // After running , Use tryLock() Try to acquire a lock , Won't wait foolishly , Try again and again through a loop , If the waiting time is long enough, , Threads always get the resources they want 
    }
}

Related articles: