J.U.C并发编程包详解 (1) Lock接口

一、Lock锁接口

  定义Java中Java.Util.concurrent 中锁 Lock 的基本接口方法

二、Lock 接口方法

Lock 接口有以下几个方法

public interface Lock {

    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

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

    void unlock();

    Condition newCondition();

}

  

lock() 是一直等到获取锁

void lock();

 

tryLock() 是尝试获取锁

boolean tryLock();

  

tryLock(Long time, TimeUnit time) 设置尝试在某个时间内获取锁,过了这个时间就不尝试获取了

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

lockInterruptibly 中止锁  

void lockInterruptibly() throws InterruptedException;

unlock( ) 解锁

unlock();

  

newCondition  稍后解释

Condition newCondition();

  

三、lock 使用

  Lock的使用,通过实现Lock接口的 ReentranLock 类来实现;

3.1、lock()  

import org.apache.tomcat.jni.Time;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockDemo {

    static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws Exception{

        lock.lock();

        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("========= Try to get lock : " + System.currentTimeMillis());
// lock 会一直等到线程可以拿到锁为止再运行 lock.lock(); System.out.println("========= Get lock : " + System.currentTimeMillis()); } }); System.out.println("========= Begin : " + System.currentTimeMillis()); th.start(); Thread.sleep(2000); System.out.println("========= After sleep: " + System.currentTimeMillis()); lock.unlock(); System.out.println("========= End : " + System.currentTimeMillis()); } }

打印

========= Begin :           1596676916634
========= Try to get lock : 1596676916636
========= After sleep:      1596676918636
========= Get lock :        1596676918637
========= End :             1596676918637

代码演示图

 说明:

(1)主线程 A 先获取到锁;

(2)启动另外一个线程 B;

(3)线程 B 尝试获取 锁,获取不到,进入锁池, 等待获取锁,运行跳回主线程A;

  (4)线程 A 进入休眠 2 秒;

(5)线程 A 休眠完,解开锁,运行并跳回线程 B;

  (6)  线程 B 获取锁;

(7)程序结束

3.2、tryLock()

public class LockDemo {

    static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws Exception{

        lock.lock();

        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("========= Try to get lock : " + System.currentTimeMillis());
                boolean get = lock.tryLock();
//这里将显示失败, 因为主线程没有释放锁,所以这个线程获取不到 System.out.println("========= Get lock : " + get ); System.out.println("======== Get lock Time : " + System.currentTimeMillis()); } }); System.out.println("========= Begin : " + System.currentTimeMillis()); th.start(); Thread.sleep(2000); System.out.println("========= After sleep: " + System.currentTimeMillis()); lock.unlock(); System.out.println("========= End : " + System.currentTimeMillis()); } }

打印

========= Begin :           1596678142300
========= Try to get lock : 1596678142300
========= Get lock :        false
======== Get lock Time :    1596678142301
========= After sleep:      1596678144300
========= End :             1596678144300

可以看到,由于这个方法,线程没有进入锁池等待获取锁,只要没有获取到锁就不等待了。

3.3、tryLock(Long time, TimeUnit time) 

public class LockDemo {

    static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws Exception{

        lock.lock();

        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("========= Try to get lock : " + System.currentTimeMillis());
                boolean get = false;
               // 线程在这里等 3秒, 获取到锁 
try { get = lock.tryLock(3000, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("========= Get lock : " + get ); System.out.println("========= Get lock Time : " + System.currentTimeMillis()); } }); System.out.println("========= Begin : " + System.currentTimeMillis()); th.start(); Thread.sleep(2000); System.out.println("========= After sleep: " + System.currentTimeMillis()); lock.unlock(); System.out.println("========= End : " + System.currentTimeMillis()); } }

打印

========= Begin :           1596678402148
========= Try to get lock : 1596678402161
========= After sleep:      1596678404148
========= End :             1596678404148
========= Get lock :        true
========= Get lock Time :    1596678404148

 3.4 lockInterruptibly( )

      线程B 等到 线程B调用 interrupt() 方法就不等了

public class InterrupteLockDemo {

    static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws Exception{

        lock.lock();

        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("========= Try to get lock : " + System.currentTimeMillis());

                try {
/*等待,获取锁,直到线程调用 interrupt(), 就不等了*/ lock.lockInterruptibly(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("========= Get lock Time : " + System.currentTimeMillis()); } }); System.out.println("========= Begin : " + System.currentTimeMillis()); th.start(); Thread.sleep(2000); System.out.println("========= After sleep: " + System.currentTimeMillis()); th.interrupt(); Thread.sleep(2000); System.out.println("========= End : " + System.currentTimeMillis()); } }

打印

========= Begin :           1596683400461
========= Try to get lock : 1596683400462
========= After sleep:      1596683402477
========= Get lock Time :   1596683402479
java.lang.InterruptedException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
    at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
    at com.jm.lock.InterrupteLockDemo$1.run(InterrupteLockDemo.java:21)
    at java.lang.Thread.run(Thread.java:748)
========= End :             1596683404478

3.5 new Condition

public class newCondition {

    static Lock lock = new ReentrantLock();
    static private Condition condition = lock.newCondition();

    public static void main(String[] args) throws Exception{

        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {

                lock.lock();
                try {
                    System.out.println("当前线程 获得锁 :  " + System.currentTimeMillis());
                    condition.await();//挂起线程
                    System.out.println("当前线程 开始执行: " + System.currentTimeMillis());

                } catch (InterruptedException e) {
                    lock.unlock();
                    e.printStackTrace();
                }

                System.out.println("========= Get lock Time :    " + System.currentTimeMillis());


            }
        });

        System.out.println("========= Begin :           " + System.currentTimeMillis());
        th.start();
        Thread.sleep(2000);
        System.out.println("========= After sleep:      " + System.currentTimeMillis());
        lock.lock();
        condition.signal();
        lock.unlock();
        System.out.println("========= End :             " + System.currentTimeMillis());

    }
}

  



原文地址:https://www.cnblogs.com/Jomini/p/13443683.html