Description: this article is talking about Java Lock
目的
在并发中,为了解决程序中多个进程和线程对资源的抢占问题,在java中引入了锁的概念
Synchronized
是java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行改短代码。
synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死多现象发生
使用synchronized时,等待的线程会一直等待下去,不能够响应中断
synchronized无法知道是否成功获取锁
修饰非静态方法,锁的是this对象
修饰静态方法,锁的是class对象
Lock
lock 是一个接口
lock发生异常时,如果没有主动通过unlock()去释放锁,则很可能会造成死锁现象,因此使用lock时需要再finally块中释放锁
lock可以让等待锁的线程相应中断
通过lock可以知道有没有成功获取锁
独占性资源
在同一个时刻每个资源只能由一个进程使用(打印机)
deadlock
两个进程独占性的访问某个资源,从而等待另外一个资源的执行结果,会导致两个进程都被阻塞,并且两个进程都不会释放各自的资源。
资源(resource)
需要排他性使用的对象称为资源,资源主要分为可抢占资源和不可抢占资源
可抢占资源(freemptable resource)
可以从拥有它的进程中抢占而不会造成其他影响,内存就是一种可抢占性资源,任何进程都能够抢先获得内存的使用权
不可抢占资源(nonfreemptable resource)
除非引起错误或者异常,否则进程无法抢占指定资源,这种不可抢占的资源比如有光盘,在进程执行调度的过程中,其他进程是不能得到该资源的
乐观锁
对于同一个数据的并发操作,乐观锁认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据,如果这个数据没有被更新,当前线程将自己修改的数据成功写入,如果数据已经被其他线程更新,则根据不同的实现方式执行不同的操作
乐观锁在Java中是通过无锁编程来实现,最常采用的是CAS算法,java原子类中的递增操作就通过CAS自旋实现的
悲观锁
认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁