在 Java 多线程中, 能够运用 synchronized 关键字来完成多线程之间同步互斥, 但在 JDK 1.5 中新增加了 ReentrantLock 类也能到达一样的效果, 并且在扩大功用上也越发壮大, 比方具有嗅探锁定, 多路分支关照, 平正锁和非平正锁等(默许)功用, 而且在运用上也比 synchronized 越发的天真.
运用 ReentrantLock 完成同步
public class MyService { private Lock lock = new ReentrantLock(); public void testMethod() { lock.lock(); for (int i = 0; i < 10; i++){ System.out.println("ThreadName=" + Thread.currentThread().getName() + (" " + (i + 1))); } lock.unlock(); } }
public class MyThread extends Thread { private MyService myService; public MyThread(MyService myService) { this.myService = myService; } @Override public void run() { myService.testMethod(); } }
public static void main(String[] args) throws IOException, InterruptedException { MyService myService = new MyService(); MyThread myThreadA = new MyThread(myService); MyThread myThreadB = new MyThread(myService); MyThread myThreadC = new MyThread(myService); MyThread myThreadD = new MyThread(myService); MyThread myThreadE = new MyThread(myService); myThreadA.start(); myThreadB.start(); myThreadC.start(); myThreadD.start(); myThreadE.start(); }
挪用 ReentrantLock 对象的 lock() 要领猎取锁, 挪用 unLock() 要领开释锁.
从运转效果来看, 当前线程打印终了以后将锁举行开释, 其他的线程才能够继承打印. 线程打印的数据是分组打印, 由于当前线程已持有锁, 但线程之间打印的递次是随机的.
运用 Condition 完成守候/关照
关键字 synchronized 与 wait() 和 notify() / notifyall() 要领连系能够完成守候/关照形式, 只不过在运用时, 挪用 notify() 要领 JVM 会随机挑选一个 WAITNG 状况的线程来实行.
而运用 Condition 则能够越发天真, 能够完成 "挑选性关照", 能够指定的挑选叫醒哪些线程, 哪些线程继承守候.
public class MyService { private Lock lock = new ReentrantLock(); public Condition conditionA = lock.newCondition(); public Condition conditionB = lock.newCondition(); public void awaitA() throws InterruptedException { lock.lock(); System.out.println("begin awaitA 时候" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); conditionA.await(); System.out.println("end awaitA 时候" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); lock.unlock(); } public void awaitB() throws InterruptedException { lock.lock(); System.out.println("begin awaitB 时候" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); conditionB.await(); System.out.println("end awaitB 时候" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); lock.unlock(); } public void signalAll_A() throws InterruptedException { lock.lock(); System.out.println("begin signalAll_A 时候" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); conditionA.signalAll(); lock.unlock(); } public void signalAll_B() throws InterruptedException { lock.lock(); System.out.println("begin signalAll_B 时候" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName()); conditionB.signalAll(); lock.unlock(); } }
public class ThreadA extends Thread { private MyService myService; public ThreadA(MyService myService) { this.myService = myService; } @Override public void run() { try { myService.awaitA(); } catch (InterruptedException e) { e.printStackTrace(); } } }
public class ThreadB extends Thread { private MyService myService; public ThreadB(MyService myService) { this.myService = myService; } @Override public void run() { try { myService.awaitB(); } catch (InterruptedException e) { e.printStackTrace(); } } }
public static void main(String[] args) throws IOException, InterruptedException { MyService myService = new MyService(); ThreadA threadA = new ThreadA(myService); threadA.setName("a"); threadA.start(); ThreadB threadB = new ThreadB(myService); threadB.setName("b"); threadB.start(); Thread.sleep(3000); myService.signalAll_A(); }
- Object 类中的 wait() 要领相当于 Condition 类中的 await() 要领.
- Object 类中的 wait(long timeout) 要领相当于 Condition 类中的 await(long time, TimeUnit unit) 要领.
- Object 类中的 notify() 要领相当于 Condition 类中的 signal() 要领.
- Object 类中的 notifyAll() 要领相当于 Condition 类中的 signalAll() 要领.
从实行效果来看, a 和 b 线程被停息, 当实行 myService.signalAll_A() 要领时, a 线程继承实行, 而 b 线程仍然是守候状况.
经常使用要领
ReentrantLock 类
int getHoldCount() 查询挪用 lock() 要领的次数.
final int getQueueLength() 预计守候锁的线程数. 比方有5个线程, 1个线程起首实行 await() 要领, 那末在挪用此要领后返回值是4, 申明有4个线程同时在守候lock的开释.
int getWaitQueueLength(Condition condition) 返回与此锁相干联给定前提守候的线程数的预计. 比方有5个线程, 每一个线程都实行了同一个 condition 对象的 await() 要领, 则挪用此要领时返回的值是5.
final boolean hasQueuedThreads() 推断是不是有线程守候此锁.
final boolean hasQueuedThread(Thread thread) 推断指定线程是不是守候猎取此锁.
boolean hasWaiters(Condition condition) 推断线程有无挪用 await() 要领.
void lockInterruptibly() throws InterruptedException 猎取锁, 除非当前线程为interrupted.
Condition 类
void awaitUninterruptibly() 和 await() 区分就是当挪用 interrupt() 要领时不会抛出 InterrputedException 非常.
本篇文章到这里就已悉数完毕了,更多其他精彩内容能够关注ki4网的Java视频教程栏目!
以上就是中ReentrantLock 类的用法引见的细致内容,更多请关注ki4网别的相干文章!