JAVA锁:synchronized和Lock

锁的类型可分为四种:
1、可重入锁(synchronized和ReentrantLock):在执行对象中,所有方法不再获取锁。
2、可中断锁(synchronized是不可中断锁,Lock是可中断锁):在等待获取中可中断
3、公平锁:(ReentranLock和ReentranReadWriteLock):按等待获取线程的等待实际进行排队,等待时间长的优先获取锁。
4、读写锁:(ReadWriteLock和ReentrantReadWriteLock):对资源的处理可分成2个部分处理,读的时候可以多线程一起读,写的时候需要获取锁权限。

synchronized和Lock的区别:

类别synchronizedLock
存在层次在JVM上是一个类
锁的获取1、如果A线程获取锁,B线程会一直等待 2、如果A线程发生堵塞,B线程会一直等待分情况而定,Lock有多个锁获取方式,大概就是尝试获得锁,线程不用一直等待(可通过tryLock判断有没有锁)
锁的释放1、线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁在finally中必须释放锁,不然容易造成线程死锁
锁的状态无法判断可以判断
锁的类型可重入、不可中断、非公平可重入、可中断、可公平(非公平也可以)
锁的性能少量同步大量同步 Lock可提高多线程的读操作效率(可以通过readwritelock实现读写分离) 在资源不是很激烈的情况下,synchronized锁的性能要优于ReetrantLock,但在资源竞争激烈的情况下,synchronized的性能将会下降几十倍,ReetrantLock的性能会维持常态。 ReetrantLock提供了多样化的同步。比如有时间限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在资源竞争不激烈的情形下,性能稍微比synchronized差点点。但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍。而ReentrantLock确还能维持常态。

synchronized

Synchronized方法锁、对象锁、类锁区别
synchronized,这个东西咱们通常称之为”同步锁“,他在修饰代码块的时候须要传入一个引用对象做为“锁”的对象。
jvm在修饰方法的时候,默认是当前对象做为锁的对象;
在修饰类时,默认是当前类的Class对象做为所的对象
故存在着方法锁、对象锁、类锁 这样的概念

方法锁(synchronized修饰方法时)
经过在方法声明中加入synchronized关键字来声明synchronized方法。
方法一旦执行,就会独占该锁,一直到从该方法返回时才将锁释放,此后被阻塞的线程方能得到该锁,从而从新进入可执行状态。
这种机制确保了同一时刻对于每个类的实例,其全部声明为synchronized的成员函数中之多只有一个处于可执行状态,从而有效避免了类成员变量的访问冲突。

对象锁(synchronized修饰方法或代码块)
当一个对象中有synchronized method或synchronized block的时候,调用此对象的同步方法或进入其同步区域的时候,必须先得到对象锁。
若此对象的锁被其它线程所调用了,就必须要等它释放锁才可调用。
java的全部对象都有一个互斥锁,这个锁由jvm自动获取和释放。
synchronized正常返回或抛异常而终止,jvm都会正常的释放锁。
1、方法锁形式参考:

public synchronized void sellTickets(){
        int i =4;
        while (i>0){
            i--;
            System.out.println(i);
        }
    }

2、代码块形式参考:

public void sellTickets2(){
        int i =4;
        synchronized (this){
            while (i>0){
                i--;
                System.out.println(i);
            }
        }
    }

类锁(synchronized修饰静态的方法或者代码块)
因为一个class不论被实例化多少次,其中的静态方法和静态变量在内存中都只有一份。因此,一旦一个静态的方法被声明为synchronized。此类全部的实例对象在调用此方法,共用同一把锁,咱们称之为类锁。
对象锁是控制实例方法之间的同步的,类锁是控制静态方法之间同步的。
类锁只是一个概念上的东西,并非真实存在的,他只是用来帮助咱们理解锁定实例方法和静态方法的区别的。
java类可能会有不少对象,可是只有一个Class(字节码)对象,也就是说类的不一样实例之间共享该类的Class对象。Class对象其实也仅仅是1个java对象,只不过有点特殊而已。
因为每一个java对象都有1个互斥锁,而类的静态方法是须要Class对象。因此所谓的类锁,只不过是Class对象的锁而已。
获取类的Class对象的方法有好几种,最简单的是[类名.class]的方式。(百度:获取字节码的三种方式)

类锁的两种方式

public static synchronized void sellTickets3(){
        int i =4;
        while (i>0){
            i--;
            System.out.println(i);
        }
    }
 public void sellTickets4(){
        int i =4;
        synchronized (TestTime.class){
            while (i>0){
                i--;
                System.out.println(i);
            }
        }
    }

Lock接口

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}

lock()、tryLock()、tryLock(long time, TimeUnit unit)和lockInterruptibly()是用来获取锁的。
unLock()方法是用来释放锁的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值