java同步锁:look 和 synchronized

一   区别 :

1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现,synchronized是在JVM层面上实现的,

不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,

lock是通过代码实现的,要保证锁定一定会被释放,就必须将 unLock()放到finally{} 中;

2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,

则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;

3)Lock可以让等待锁的线程响应中断,线程可以中断去干别的事务,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;

4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。

5)Lock可以提高多个线程进行读操作的效率。


在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。






二   lock  接口实现类

public interface Lock {
    //获取锁,如果锁被暂用则一直等待
    void lock();
    //用该锁的获得方式,如果线程在获取锁的阶段进入了等待,那么可以中断此线程,先去做别的事  
    void lockInterruptibly() throws InterruptedException;
    //注意返回类型是boolean,如果获取锁的时候锁被占用就返回false,否则返回true
    boolean tryLock();
    //比起tryLock()就是给了一个时间期限,保证等待参数时间
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    //释放锁
    void unlock();
}

三、唯一实现类:ReentrantLock  获取锁定与三种方式:

a) lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁

b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
c)tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;

d) lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断


四  synchronized  和  volatile

3.可见性-synchronized java内存模型(JMM)关于synchronized的两条规定: A.线程解锁前,必须把共享变量的最新值刷新到主内存 B.线程加锁时,将清空工作内存中的共享变量的值,从而在使用共享变量时,
    需要从主内存中重新读取最新的值(注意:加锁和解锁是同一把锁)  4.可见性-volatile (1).通过加入内存屏障和禁止重排序优化来实现 A.对volatile变量写操作时,会在写操作后加入一条store屏障指令,将本地内存中的共享变量值刷新到主内存 B.对volatile变量读操作时,会在读操作前加入一条load屏障指令,从主内存中读取共享变量
    通俗地说就是,volatile变量每次被线程访问时,都强迫从主内存读取该变量的值,而当该变量发生变化时,
    又会强迫线程将最新的值刷新到主内存,这样,任何时候不同的线程总能看到该变量的最新值







全部评论

相关推荐

03-29 12:10
门头沟学院 C++
挣K存W养DOG:散漫消极者淘汰,一眼坑爹。实习几个月转正的时候说你加班太少,能力还行态度不够积极裁了,马上老实。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务