一 synchronized 内置锁和Lock的比较
相同点:都能够防止多线程同时访问共享资源
都支持重进入锁
不同点:
内置锁获取锁和释放锁是隐式的,不需要程序员手动去管理锁;Lock需要显示地获取和释放锁,灵活性也更大,如果没有释放锁,可能会导致死锁。
内置锁获取锁的顺序都是无序的;Lock可以构造公平锁,这样就会按照线程到来的时间先后顺序来获取锁
内置锁抛出异常的时候,释放锁;但是Lock获取锁之后,如果程序出现异常,不会释放锁,必须手动释放,这些是为什么lock必须在有异常时必须在finally块中释放锁
内置锁如果线程处于阻塞状态,是不能被中断的,只有一直等下去;Lock如果使用lock.Interruptibly则是可以中断线等待状态
内置锁,死锁了必须重启;Lock提供了一套定时锁机制,tryLock(long time, TimeUnit unit),在规定时间内,仍然没有获得锁,当前线程就放弃,就当没有这个线程。
内置锁读写都是互斥的;但是Lock的读写锁可以实现读读不互斥,其余的互斥
二 lock()与tryLock比较
lock函数是阻塞的,如果锁被其他线程获取,当前线程一直就在这等;tryLock是非阻塞的,调用后立即返回,拿到锁了返回true,没有拿到返回false都需要手动释放锁
执行结果:
结论:获取锁的线程执行完毕,其他线程才能进入,否则一直处于阻塞状态
使用tryLock,如果线程没有抢到锁,返回false,则不再继续等待锁。如果设置了超时时间,如果没有抢到锁,并且在给定的超时间内仍然没有抢到。,返回false,不再继续等待锁,可能这时候去干别的事情
三 lock.lock 和 lock.lockInterruptibly 比较
lock.lock获取锁的过程中,忽略中断,在成功获取锁后,再根据中断标志处理中断。lock.lock.lockInterruptibly,如果线程正在等待获取锁,则这个线程被中断,就会立即中断线程等待状态,比如当两个线程同时通过lock.lockInterruptibly()想获取某个锁时,假若此时线程A获取到了锁,而线程B只有在等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程
运行结果:
A线程获取锁,还没有运行完毕,B线程处于等待,然后中断B线程,此时B线程会立即中断,并抛出异常,然后释放锁,但是没有获取到锁,所以抛出这个错误
注意,当一个线程获取了锁之后,是不会被interrupt()方法中断的。因为本身在前面的文章中讲过单独调用interrupt()方法不能中断正在运行过程中的线程,只能中断阻塞过程中的线程。
四 ObjectMonitor 和 Condition的比较
调用方式不一样:前者通过Object.调用wait,notify,notifyAll; 后者调用Condition的await,singal,singalAll方法进入等待状态是否释放锁:Wait方法:调用之后,释放锁,其他线程可以进入;await一致阻塞,必须手动释放。
是否能唤醒部分线程:前者只能唤醒一个或者全部;后者可以唤醒部分线程