以前都没注意到锁,一直用着 synchronized 以为就万事大吉了。
突然发现还有另外一种,而且另外一种针对于读取的操作(资源竞争激烈)更具有优势
先上代码:
package test.thread; import java.util.concurrent.locks.ReentrantReadWriteLock; public class LSThreadTest { private int j = 0; private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); public static void main(String[] args) { // TODO Auto-generated method stub LSThreadTest tt = new LSThreadTest(); Inc inc = tt.new Inc(); Dec dec = tt.new Dec(); Sel sel = tt.new Sel(); Thread thread = new Thread(inc); thread.start(); thread = new Thread(dec); thread.start(); for (int i = 0; i < 4; i++) { thread = new Thread(sel); thread.start(); } } private void inc() { rwl.writeLock().lock(); try { j++; System.out.println(Thread.currentThread().getName() + " j:" + j); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { rwl.writeLock().unlock(); } } private void dec() { rwl.writeLock().lock(); try { j--; System.out.println(Thread.currentThread().getName() + " j:" + j); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { rwl.writeLock().unlock(); } } class Inc implements Runnable { public void run() { for (int i = 0; i < 10; i++) { inc(); } } } class Dec implements Runnable { public void run() { for (int i = 0; i < 10; i++) { dec(); } } } private void sel() { rwl.readLock().lock(); try { System.out.println(Thread.currentThread().getName() + " j:" + j); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { rwl.readLock().unlock(); } } class Sel implements Runnable { public void run() { for (int i = 0; i < 10; i++) { sel(); } } } }
ReentrantReadWriteLock 在 写锁的时候,是不会被打扰到。同时在读的时候却是可以一起读。