Java知识点之锁
作者:互联网
1、Synchronized
对象锁
对象锁是针对于对象的,也就是说一个对象就有一把锁。这个锁由JVM控制获取和释放。当一个对象被多个线程访问synchronized修饰的方法或者代码块的时候,那么最先获取锁的线程先执行此方法,其他线程等待。线程在执行过程中抛出异常而终止或者执行完代码块正常返回时JVM会自动释放锁,又进行下一轮竞争(注:当前线程还参与竞争的话与其他线程是平等的)
synchronized method()
代表对象的方法同步,多个线程同时调用某个对象的此方法时会竞争,不同对象之间的此方法互不干扰
synchronized(obj)
代表对象的某一块代码块同步
类锁
其实没有所谓的类锁,类锁只是为了区别类的成员方法和静态方法。因为类的静态成员是不归属于类的实例对象的(类名可以直接调用),所以当多个线程同时调用类的静态方法时,如果不加锁,那么和普通调用一样没什么区别,n个线程可能同时执行这个方法;如果加了锁,那么n个线程就会依次执行这个方法
public synchronized static void method()
代表n个线程同一时刻只能有一个线程执行
注:在synchronized修饰的代码块中使用sleep()方法会使当前线程放弃CPU执行权,但并不会让当前线程放弃同步锁
2、Lock
(1)Lock加的锁必须手动释放,如果程序在执行过程中出现异常,但是没有捕获异常,那么此时程序可能会出现死锁
(2)两个线程同时尝试去获取锁,获取到就执行run()方法中的逻辑代码,否则不执行。这种情况,最少有一个线程中的逻辑代码会被执行
lock
加锁
unlock
取消锁
tryLock
尝试去获取一次锁
tryLock(long time, TimeUnit unit)
在这个时间段内一直尝试去获取锁
lockInterruptibly
允许在等待时由其他线程的Thread.interrupt()
方法来中断等待线程而直接返回,这时是不用获取锁的,而会抛出一个InterruptException
3、wait()、notify()、notifyAll()
调用前提是获取了同一把对象锁,否则会抛出IllegalMonitorStateException(非法监听状态异常)
wait()
wait方法是让出对象锁,让出当前的CPU时间片,线程休眠
notify()
notify不会让当前线程休眠,可以唤醒其他线程。notify唤醒通知其他线程后就不管了,然后其他线程竞争获取CPU时间片
notifyAll()
notifyAll不会让当前线程休眠,会唤醒所有等待的线程
4、sleep()和wait()的区别
(1)sleep
方法实现的是“线程睡眠”,即当前线程休眠了指定时间之后,就自动苏醒
(2)wait
方法实现的是“线程等待”,如果没有到指定等待时间(或时间为0)或者没有接收到通知,则一直等待
标签:知识点,之锁,Java,synchronized,对象,获取,线程,方法,wait 来源: https://blog.csdn.net/qq_40833790/article/details/94872750