设为首页 加入收藏

TOP

Java并发编程-各种锁(三)
2018-03-18 16:21:30 】 浏览:814
Tags:Java 并发 编程 各种

                System.out.println(Thread.currentThread().getName() + "B锁获取成功");
            }
        }
    }


}


运行结果如下:



可以看到把业务逻辑抽离出来,把获取锁的代码放在一个公共的方法里面,获得锁都必须始终遵守这个既定的顺序。


2.引入显式锁的超时机制特性来避免死锁


超时机制是监控死锁和从死锁中恢复的技术,是使用每个显式所Lock类中定时tryLock特性,来替代使用颞部所机制。在内部锁的机制中,只要没有获得锁,就永远保持等待,而


显示的锁使你能狗定义超时的时间,在规定时间之后tryLock还没有获得锁就会返回失败。通过使用超时,尽管这段时间比你预期能够获得所的时间长很多,你仍然可以在意外发生后重新


获得控制权。当尝试获得定时锁失败时,你并不需要知道原因。也许是因为有死锁发生,也许是线程在持有锁的时候错误地进入无限循环;也有可能是执行一些活动所花费的时间比你


预期慢了许多。不过至少你有机会了解到你的尝试已经失败,记录下这次尝试中有用的信息,并重新开始计算,这远比关闭整个线程要优雅得多。


  即使定时锁并没有应用于整个系统,使用它来获得多重锁还是能够有效应对死锁。如果获取锁的请求超时,你可以释放这个锁,并后退,等待一会后再尝试,这很可能消除了死锁发生的条件,


并且循序程序恢复。(这项技术只有在同时获得两个锁的时候才有效;如果多???锁是在嵌套的方法中被请求的,你无法仅仅释放外层的锁,尽管你知道自己已经持有该锁)


显式锁Lock,Lock是一个接口,定义了一些抽象的所操作。与内部锁机制不同,Lock提供了无条件,可轮询,定时的,可中断的锁获取操作,所有加锁和解锁的方法都是显式的。


Lock的实现必须提供举报与内部锁相同的内存可见性的语义。但是加锁的语义,调度算法,顺序保证,性能特性这些可以不同。


Lock接口源码如下:


public interface Lock {
    //加锁    void lock();


    //可中断的锁,打算线程的等待状态,即A线程已经获取该锁,B线程又来获   
    //取,但是A线程会通知B,来打算B线程的等待。    void lockInterruptibly() throws InterruptedException; 
    //尝试去获取锁,失败返回False    boolean tryLock();



    //超时机制获取锁    boolean tryLock(long time, TimeUnit unit) throws
    InterruptedException;


    //释放锁    void unlock();


    Condition newCondition();


}


ReentranLock实现了Lock接口,提供了与synchronized相同的互斥和内存可见性的保证。获得ReentrantLock的锁与进入synchronized块有着相同内存含义,释放ReentrantLock锁与退出synchronized块有着相同内存含义。


ReentrantLock提供了与synchronized一样可重入加锁的语义。ReentrantLock支持Lock接口定义的所有获取锁的方式。与synchronized相比,ReentranLock为处理不可用的锁提供了更多灵活性。


但是对于现在的JDK的更新,synchronized的性能被优化的越来越好,内部锁(synchronized)已经获得相当可观的性能,性能不仅仅是个不断变化的目标,而且变化的非常快。


如下图:



看到图,随着JDK的更新迭代,内部锁的性能越来越快,这不是ReentrantLock的衰退,而是内部锁(synchronized)越来越快,特别在JDK目前跟新到现在1.9.


下面用显式锁Lock再来改造上面的例子


public class DeadLock {


    Lock lock = new ReentrantLock();


    private static Object lockA = new Object();


    private static Object lockB = new Object();


    public static void main(String[] args) {
        new DeadLock().deadLock();
    }


    private void deadLock() {


        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                try {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + "获取A锁 ing!");
                    Thread.sleep(500);
                    System.out.println(Thread.currentThread().getName() + "睡眠500ms");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
    &nb

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 3/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇二叉搜索树介绍及其接口说明 下一篇在Kotlin中使用Gradle构建缓存

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目