Java同步锁------synchronized和lock

Synchronized

synchronized可用很好的解决多线程并发安全问题,但是在有些时候,他会使机器的性能降低,就比如在同步锁内部发生IO阻塞,导致了其他想获得锁的线程不能获得,一直阻塞在那里,这样大大降低的程序的运行效率。

经过总结synchronized有如下缺点:

(1)如果获得锁的线程发生了IO阻塞,或者调用了sleep方法,那么这样jvm是不会释放锁的(当线程发生异常,jvm才会让线程自动释放锁),这么一来,在阻塞过程中,cpu就空转了,其他线程得不到锁,这样降低了机子的性能。

(2)如果多线程进行读写文件时,读操作和写操作会发生冲突,写操作和写操作会发生冲突,读操作和写操作不会发生冲突,但是采用了synchronized,无论以上哪种情况,都会阻塞,我们知道,读操作和读操作是可用并发执行的,如果不阻塞可用提高性能。

综合以上2个缺点:就有了lock。lock可以很好的解决以上问题,针对第一个,lock可以通过设置锁的超时时间,超过设定时间就自动释放锁;针对第二点,lock就有相应的读锁和写锁。

Lock

lock是个接口,接口中有四个方法lock()、trylock()、trylock(long time, TimeUnit unit)、lockInterruptibly()来获取锁。

用unlock()来释放锁。

(1)lock是平常使用最多的一个方法,lock必须手动释放,在发生异常的时候,jvm是不会取释放锁的,因此在用lock时候,要写在try{}catch{}里面,并且在finally{}中去释放锁,避免死锁。

(2)trylock(),字面理解尝试获得锁,当trylock获得成功,就返回true,否则返回false,优点在于在拿不到锁的时候,不会一直等待,而会继续执行其他。

(3)trylock(long time, TimeUnit unit)和trylock()类似,就是多了参数,表示在指定时间仍然不能获取锁,那么返回false,否则返回true。

(4)lockInterruptibly(),举例:两个线程A、B通过lock.lockInterruptibly()获取锁,A先获得锁,B只能等待,那么B可以调用interrupt(),来中断B的等待。

lock需要我们自己去实现,显然不方便,那么就有ReentrantLock实现类,意思是“可重入锁”。


ReadWriteLock

ReadWriteLock是接口;其实现类是ReentrantReadWriteLock,主要有两个方法:readLock()和writeLock()

注意:

  不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。

    原文作者:java锁
    原文地址: https://blog.csdn.net/m0_37746890/article/details/79151220
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞