相比于ReetrantLock,使用synchronized来编写代码要简洁的多,之所以能使用synchronized,是因为每个对象都有一个内部锁,并且该锁有一个内部条件。由锁来管理那些试图进入synchronized方法的线程,由条件来管理那些调用wait的线程
将静态方法声明为synchronized也是允许的,如此则会获得特定类的内部锁,如一个类Person,当该方法被调用时,该方法将会获得Person.class上的锁,并且,没有其他线程可以调用Person类的其他同步静态方法
tryLock()方法试图申请一个锁,申请成功返回true,否则返回false,并且线程可以立即离开去做其他事
if(myLock.tryLock()){ try{...} finally{ myLock.unlock(); } }else{ }
- lock()方法不能被中断,但是带有超时参数的tryLock方法可以被中断,并且抛出InterruptedException. lockInterruptibly()方法,相当于一个超时设为无限长的方法,它可以被中断。
- 使用await方法是自己进入等待的线程,如果被打断,也会抛出InterruptedException,awaitUnInterruptibly()方法将不会被打断
- ReentrantReadWriteLock可重入读写锁,如果在很多线程并发读而较少线程并发写的情况下,是十分有用的。
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock ();
private Lock readLock = rwl.readLock();
private Lock writeLock = rwl.writeLock();
然后,对所有的读方法加读锁,对所有的写方法加写锁。
java.util.concurrent.locks.ReentrantReadWriteLock
- Lock readLock()
得到一个可以被多个读操作共用的读锁,但会排斥所有写操作 - Lock writeLock()
得到一个写锁,排斥其他的读操作和写操作 - 如果在多线程环境中使用阻塞队列,应该使用put和take方法添加和移除元素,因为这两个方法在遇到队列满或队列空的情况下,会阻塞。并且,一定要使用offer、poll、peek方法替代add、remove、和element方法,因为后者会抛出异常,而前者则返回null