多线程中锁的种类。
1. 可重入锁
ReentrantLock 和 synchronized 都是可重入锁。
1 class Main{ 2 public synchronized void method1() { 3 method2(); 4 } 5 6 public synchronized void method2() { 7 8 } 9 }
在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。如果不具有可重入性,则会造成死锁。
2. 可中断锁
Lock 是可中断锁,而synchronized 不是可中断锁。
如果某一线程A正在执行锁中的代码,另一线程B正在等待获取该锁,可能由于等待时间过长,线程B不想等待了,想先处理其他事情,我们可以让它中断自己或者在别的线程中中断它,这种就是可中断锁。
3. 公平锁
synchronized 是非公平锁,它无法保证线程获取锁的顺序。ReentrantLock 与 ReentrantReadWriteLock,它默认情况下是非公平锁,但是可以设置为公平锁。
公平锁即尽量以请求锁的顺序来获取锁。比如同时有多个线程在等待一个锁,当这个锁被释放时,等待时间最久(最先请求)的的线程会获得该锁,这种就是公平锁。
1 public ReentrantLock() { 2 sync = new NonfairSync(); 3 } 4 5 public ReentrantLock(boolean fair) { 6 sync = fair ? new FairSync() : new NonfairSync(); 7 }
如果参数为true表示为公平锁,为fasle为非公平锁。默认情况下,如果使用无参构造器,则是非公平锁。
4. 读写锁
读写锁使得多个读操作不会发生冲突。
如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
1 public void get(Thread thread) { 2 ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 3 rwlock.readLock().lock(); 4 try { 5 long start = System.currentTimeMillis(); 6 7 while(System.currentTimeMillis() - start <= 1) { 8 System.out.println(thread.getName()+"正在进行读操作"); 9 } 10 System.out.println(thread.getName()+"读操作完毕"); 11 } finally { 12 rwlock.readLock().unlock(); 13 } 14 }