DWQA QuestionsCategory: ProgramUse of lock. Trylock() method
Bodhi Asahi asked 8 months ago
package concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestTryLock {

    private List<Object> list = new ArrayList<Object>();
    private Lock         lock = new ReentrantLock();

    public static void main(String[] args) {
        final TestTryLock test = new TestTryLock();
        New thread ("first thread"){

            @Override
            public void run() {
                test.doSomething(Thread.currentThread());
            }
        }.start();

        New thread ("second thread"){

            @Override
            public void run() {
                test.doSomething(Thread.currentThread());
            }
        }.start();
    }

    public void doSomething(Thread thread) {
        if (lock.tryLock()) {
            try {
                System. Out. Println (thread. Getname() + "got lock.");
                for (int i = 0; i < 10; i++) {
                    list.add(i);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                System. Out. Println (thread. Getname() + "released lock.");
                lock.unlock();
            }
        } else {
            System. Out. Println (thread. Getname() + "failed to get lock.");
        }
    }
}

The above code runs as follows:

The first thread gets the lock
The first thread released the lock
The second thread gets the lock
The second thread released the lock
package concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestTryLock {

    private List<Object> list = new ArrayList<Object>();
    private Lock         lock = new ReentrantLock();

    public static void main(String[] args) {
        final TestTryLock test = new TestTryLock();
        New thread ("first thread"){

            @Override
            public void run() {
                test.doSomething(Thread.currentThread());
            }
        }.start();

        New thread ("second thread"){

            @Override
            public void run() {
                test.doSomething(Thread.currentThread());
            }
        }.start();
    }

    public void doSomething(Thread thread) {
        if (lock.tryLock()) {
            try {
                System. Out. Println (thread. Getname() + "got lock.");
                for (int i = 0; i < 10; i++) {
                    list.add(i);
                    Thread.sleep(10);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                System. Out. Println (thread. Getname() + "released lock.");
                lock.unlock();
            }
        } else {
            System. Out. Println (thread. Getname() + "failed to get lock.");
        }
    }
}

The operation results are as follows:

The second thread gets the lock
The first thread failed to acquire the lock
The second thread released the lock

The questions are as follows:
I know that the lock () method gets the lock. When it can’t get the lock, it will wait all the time. Until the lock is acquired.
When the trylock() method acquires the lock, it makes a trial. If it fails to acquire the lock, it will not wait all the time. If so, as my demo shows, using trylock in business logic can easily cause the program to be out of control. I wonder how to use this trylock.. Ask God to explain.. Thank you.

huqian replied 8 months ago

Thanks, but Java doesn’t use much. For example, if you want to edit a wiki page at the same time, you don’t have to edit it successfully, or you can give up being a draft.

4 Answers
Best Answer
magooup answered 8 months ago

This is the bestLockCompare the four lock methods of (let me copy something):

  • void lock();

If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired.

Sleep while waiting to acquire lock and disable all thread scheduling

  • void lockInterruptibly() throws InterruptedException;

If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happens:
The lock is acquired by the current thread; or Some other thread interrupts the current thread, and interruption of lock acquisition is supported.

Can be interrupted while waiting for a lock to be acquired

  • boolean tryLock();

Acquires the lock if it is available and returns immediately with the value true. If the lock is not available then this method will return immediately with the value false.

Get lock and return true; get no and return false

*boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

If the lock is available this method returns immediately with the value true. If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:The lock is acquired by the current thread; or Some other thread interrupts the current thread, and interruption of lock acquisition is supported; or The specified waiting time elapses.

Wait for the lock to be acquired within the specified time; the process can be interrupted

If threadAAnd threadBUse the same lockLOCKAt this time, thread a first obtains the lockLOCK.lock(), and is always held without release. If B wants to acquire the lock at this time, there are four ways:

  • LOCK.lock(): this mode will always be waiting, even if calledB.interrupt()It cannot be interrupted unless thread a callsLOCK.unlock()Release the lock.
  • LOCK.lockInterruptibly(): this method will wait, but when calledB.interrupt()Will be interrupted waiting and thrownInterruptedExceptionAbnormal, otherwise it willlock()The same remains in wait until thread a releases the lock.
  • LOCK.tryLock(): there will be no waiting. If the lock cannot be acquired, it will directly return to false to execute the following logic.
  • LOCK.tryLock(10, TimeUnit.SECONDS): this location will be waiting for 10 seconds, but when calledB.interrupt()Will be interrupted waiting and thrownInterruptedException。 If thread a releases the lock within 10 seconds, it will get the lock and return true. Otherwise, it will not get the lock after 10 seconds and return false to execute the following logic.

Will it causeProgram out of control, not in these ways, but in the business category and usage logic.

MartinDai answered 8 months ago

Why does it make the program uncontrollable? CalltryLockThe result will be returned immediately after the method, and the corresponding business operation will be made according to whether the lock is obtained or not, compared withlockMethod will block all the time, which makes the program more controllable.

jiangxiao answered 8 months ago

Different methods have different uses, but the application scenarios are different, not uncontrollable

fredric_2016 answered 8 months ago

The understanding of program controllability here refers to that every task is executed as required, but I think since the non blocking scenario of trylock() is used, it is necessary to allow some tasks not to execute (for example, to prevent repeated submission of business), or not to execute (for example, to prevent resource waiting queue overflow), etc.