码迷,mamicode.com
首页 > 其他好文 > 详细

Lock锁-Lock接口

时间:2020-04-22 14:54:13      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:dea   说明   deadlock   getname   死锁   结果   pack   style   star   

本文从以下几个方面介绍Lock接口,分别从lock锁的介绍、为什么要用lock锁、方法介绍、可见性保证

Lock接口简介

  Lock锁是一种工具,用来控制对共享资源的访问。

  Lock锁和Synchronized锁两者各个有各自的使用场景,lock并不是来替换Synchronized锁的。

  Lock接口最常见的实现类是ReentrantLock

Lock接口方法

  lock接口中包含如下四个方法,分别是:lock()、tryLock()、tryLock(long time,TimeUnit unit)和lockInterruptibly(),接下来会详细介绍这四种方法是如何使用的,见下所示。

lock method

  lock方法是普通的获取锁的方法,lock方法不会像synchronized方法一样在异常发生时自动释放锁,lock方法需要手动释放锁。所以在使用lock锁时一定要手动释放锁。

  见下面的实现,如下

  

package com.yang.lock;

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

/**
 * lock不会自动释放锁,我们采用try -finally的方式实现,必须手动释放锁
 */
public class MustUnlock {
    private static Lock lock=new ReentrantLock();

    public static void main(String[] args) {
        lock.tryLock();
        try{
            //制定锁定的资源,我们可以采用模拟的方式实现
            System.out.println(Thread.currentThread().getName());
        }finally {
            lock.unlock();
        }
    }
}

 

  使用lock方法时,当产生死锁时,会永久等待,即为lock锁的弊端。所有有个tryLock的方法,接下来我们一起看下tryLock方法

 

tryLock method

   tryLock此方法用来尝试获取锁,如果当前锁没有被其他线程占用的时候,才是可以获取成功的,该方法的返回值为True,若返回False则说明锁没有获取成功

 

tryLock(long time,TimeUnit unit) method

     此方法相比上面方法多了尝试锁的等待时间,下实例模拟两个线程获取两把锁,见下代码。

   

package com.yang.lock;

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

/**
 * 尝试获取锁,若能获取到锁,则返回true,否则返回false
 * 用来避免死锁问题
 * 某次的运行结果如下:
 * 线程2取到了锁1
 * 线程1取到了锁1
 * 线程1获取锁2失败了,已经重试了
 * 线程2获取到了锁2
 * 线程2成功获取了两把锁
 * 线程1取到了锁1
 * 线程1获取到了锁2
 * 线程1成功获取了两把锁
 *
 * Process finished with exit code 0
 */
public class TryDeadLock implements Runnable {
    private static Lock lock1 = new ReentrantLock();
    private static Lock lock2 = new ReentrantLock();
    int flag = 1;

    public static void main(String[] args) {
        TryDeadLock tryDeadLock1=new TryDeadLock();
        tryDeadLock1.flag=0;
        TryDeadLock tryDeadLock2=new TryDeadLock();
        tryDeadLock2.flag=1;
        new Thread(tryDeadLock1).start();
        new Thread(tryDeadLock2).start();

    }
    @Override
    public void run() {
        //模拟实现死锁
        for (int i = 0; i < 100; i++) {
            if (flag == 1) {
                try {
                    if (lock1.tryLock(800, TimeUnit.MILLISECONDS)) {
                        try {
                            System.out.println("线程1取到了锁1");
                            Thread.sleep(new Random().nextInt(1000));
                            if (lock2.tryLock(800, TimeUnit.MILLISECONDS)) {
                                try {
                                    System.out.println("线程1获取到了锁2");
                                    System.out.println("线程1成功获取了两把锁");
                                    break;

                                } finally {
                                    lock2.unlock();
                                }
                            } else {
                                System.out.println("线程1获取锁2失败了,已经重试了");
                            }
                        } finally {
                            lock1.unlock();
                            Thread.sleep(new Random().nextInt(1000));
                        }
                    } else {
                        System.out.println("线程1获取锁1失败了,已经重试了");
                    }
                } catch (Exception e) {

                } finally {

                }
            } else {
                try {
                    if (lock2.tryLock(3000, TimeUnit.MILLISECONDS)) {
                        try {
                            System.out.println("线程2取到了锁1");
                            Thread.sleep(new Random().nextInt(1000));
                            if (lock1.tryLock(800, TimeUnit.MILLISECONDS)) {
                                try {
                                    System.out.println("线程2获取到了锁2");
                                    System.out.println("线程2成功获取了两把锁");
                                    break;

                                } finally {
                                    lock1.unlock();
                                }
                            } else {
                                System.out.println("线程2获取锁2失败了,已经重试了");
                            }
                        } finally {
                            lock2.unlock();
                            Thread.sleep(new Random().nextInt(1000));
                        }
                    } else {
                        System.out.println("线程2获取锁1失败了,已经重试了");
                    }
                } catch (Exception e) {

                } finally {

                }
            }
        }
    }
}

  

lockInterruptibly method

  本文

  

Lock锁-Lock接口

标签:dea   说明   deadlock   getname   死锁   结果   pack   style   star   

原文地址:https://www.cnblogs.com/cnxieyang/p/12751973.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!