大纲:
- Lock接口
- synchronized&Lock异同
一、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()获取锁。
- lockInterruptibly()可打断的获取锁方法,仅可打断等待锁的线程。
- tryLock()获取锁并返回结果,得到锁的线程返回true,没有拿到锁的线程不再等待并返回false。
- tryLock(time)带参数函数,可以传入一个时间,在这个时间内获得锁的线程返回true,没有获得锁返回false,且在这个时间内等在锁的线程可以被打断。
- unlock()释放锁。
- newCondition 创建一个场景(见下章)。
注意:打断正在获取锁的线程时,lockInterruptibly,tryLock都会抛出InterruptedException。此时不能用try,catch,finally结构将InterruptedException捕获,执行finally中的unlock操作,因为该线程并没有获得锁,unlock操作也会报错。因此最好将这个InterruptedException向上抛出,由上级try,catch。
例:
ReentrantLock为Lock接口唯一实现类
public class Met { Lock lock = new ReentrantLock(); public void action(Thread thread) throws InterruptedException { if(lock.tryLock(2, TimeUnit.SECONDS)){ try { System.out.println(thread.getName()+"lock"); for(int i =0;i<20000;i++){ System.out.println(thread.getName()+":"+i); } } finally { System.out.println(Thread.currentThread().getName()+"run finally"); lock.unlock(); System.out.println(thread.getName()+"unlock"); } } } }
public class MyRunnable implements Runnable { Met met; MyRunnable(Met met){ this.met = met; } @Override public void run() { try { met.action(Thread.currentThread()); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName()+"interrupted"); } } }
class TestLock { public static void main(String[] args) { Met met = new Met(); MyRunnable myRunnable0 = new MyRunnable(met); MyRunnable myRunnable1 = new MyRunnable(met); Thread thread0 = new Thread(myRunnable0); Thread thread1 = new Thread(myRunnable1); thread0.start(); thread1.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } thread1.interrupt(); } }
本例执行后,线程1被打断,由于是trylock(2分钟),因此抛出中断异常,上级catch后打出日志
Thread-0:2865 Thread-0:2866 Thread-1被中断 Thread-0:2867 Thread-0:2868 Thread-0:2869
二、synchronized&Lock异同
- synchronized代码块内发生异常,锁会自动释放、lock需要在finally中手动释放。
- synchronized无法锁的获取情况。
- synchronized无法设置超时。
- synchronized无法中断等待获取锁的线程。
- synchronized无法设置是否公平锁,lock和synchronized默认是非公平锁。
- 大并发,lock性能优于synchronized。
- lock和synchronized都是排他、重入锁。