一、效果和synchronized同样,均可以同步执行,lock方法得到锁,unlock方法释放锁java
使用示例:ide
package com.test; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyService { private Lock lock = new ReentrantLock(); public void methodA() { try { lock.lock(); System.out.println("methodA begin ThreadName = " + Thread.currentThread().getName() + "time=" + System.currentTimeMillis()); Thread.sleep(3000); System.out.println("methodA end ThreadName = " + Thread.currentThread().getName() + "time=" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void methodB() { try { lock.lock(); System.out.println("methodB begin ThreadName = " + Thread.currentThread().getName() + "time=" + System.currentTimeMillis()); Thread.sleep(3000); System.out.println("methodB end ThreadName = " + Thread.currentThread().getName() + "time=" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
package com.test; public class Run { public static void main(String[] args) { MyService myService = new MyService(); Thread t1 = new Thread(new Runnable() { @Override public void run() { myService.methodA(); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { myService.methodB(); } }); t1.start(); t2.start(); } }
结果: methodA begin ThreadName = Thread-0time=1527821296840 methodA end ThreadName = Thread-0time=1527821299841 methodB begin ThreadName = Thread-1time=1527821299841 methodB end ThreadName = Thread-1time=1527821302841
注意:必需要在finally块里调用lock.unlock() 释放锁.spa
二、使用Condition实现等待/通知:线程
awati() 与 signal() 方法:code
package com.test; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyService { private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void testWait() { try { lock.lock(); System.out.println("wait"); condition.await(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void testSignal() { try { lock.lock(); condition.signal(); } finally { lock.unlock(); } } }
三、公平锁和非公平锁:对象
公平锁标识线程获取锁的顺序是按照线程加锁的顺序来分配的。即先来先得的FIFO先进先出顺序。而非公平锁就是一种获取锁的抢占机制,是随机得到锁的。blog
Lock lock=new ReentrantLock(true);//公平锁 Lock lock=new ReentrantLock(false);//非公平锁
四、ReentrantLock 类的方法:get
五、ReentrantReadWriteLock 类,读写锁:同步
类ReentrantLock 具备彻底互斥排他的效果,即同一时间只有一个线程在执行lock()方法后面的任务。it
读写锁表示也有两个锁,一个是读操做相关的锁,也成为共享锁;另外一个是写操做相关的锁,也就排它锁。也就是多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。在没有线程进行写操做时,进行读取操做的多个线程均可以获取读锁,而进行写入操做的线程只有在获取写锁后才能进行写入操做。即多个线程能够同时进行读操做,但同一时刻只有一个线程能够进行写操做。
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void read() { try { try { lock.readLock().lock(); System.out.println("获取读锁:" + System.currentTimeMillis()); Thread.sleep(1000); } finally { lock.readLock().unlock(); } } catch (Exception e) { e.printStackTrace(); } }
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void write() { try { try { lock.writeLock().lock(); System.out.println("获取写锁:" + System.currentTimeMillis()); Thread.sleep(1000); } finally { lock.writeLock().unlock(); } } catch (Exception e) { e.printStackTrace(); } }
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void read() { try { try { lock.writeLock().lock(); System.out.println("获取读锁:" + System.currentTimeMillis()); Thread.sleep(1000); } finally { lock.writeLock().unlock(); } } catch (Exception e) { e.printStackTrace(); } } public void write() { try { try { lock.writeLock().lock(); System.out.println("获取写锁:" + System.currentTimeMillis()); Thread.sleep(1000); } finally { lock.writeLock().unlock(); } } catch (Exception e) { e.printStackTrace(); } }
lock 与 lockInterruptibly比较区别在于:
lock 优先考虑获取锁,待获取锁成功后,才响应中断。
lockInterruptibly 优先考虑响应中断,而不是响应锁的普通获取或重入获取
synchronized 和 lock 的用法区别:
使用ReentrantLock的场景: