synchronized:同步锁,是java内置的关键字。当一个线程A执行到被synchronized修饰的方法时,其他线程B如果也要执行这个方法,那么B只能等A执行完方法释放锁后才能获取资源锁执行synchronized方法块。
synchronized释放锁的情况
1,执行完改代码块,释放锁
2,执行时发生异常,jvm自动释放
lock:是一个类,通过这个类可以实现同步访问
lock和synchronized最大不同点。lock释放锁需要手动释放,如果没有手动释放则会导致死锁的现象
而synchronized则不需要手动释放,会自动释放锁
lock可以知道线程有没有获取到锁,而synchronized则不能
lock可以提供机制使多个线程同时进行读或者写的操作,而synchronized则不能
tryLock()方法有返回值,表示用来尝试获取锁,如果成功则返回true,如果失败则返回false。它都是立即返回的。在拿不到锁时不会等待
Lock lock = ...; if(lock.tryLock()) { try{ //处理任务 }catch(Exception ex){ }finally{ lock.unlock(); //释放锁 } }else { //如果不能获取锁,则直接做其他事情 }
lockInterruuptibly()方法:可以通过这个方法获取锁,如果线程正在等待获取锁,则这个线程能够响应中断
例子:a获取了锁,而b在等待获取锁,那么b可以调用interuuptibly()方法结束等待
public void method() throws InterruptedException { lock.lockInterruptibly(); try { //..... } finally { lock.unlock(); } }
ReentrantLock 重入锁
1. ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。
2. ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。
3. ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。
ReadWriteLock 读写锁
实现了ReentrantLock接口
读写锁,可以通过读方法或者写方法使多个线程同时进行读或者写,提高线程效率
注意,读和写是互斥的,如果a获取到读方法的锁,如果他在要去获取写方法的锁那么他是获取不到的