前言:本系列将从零开始讲解java多线程相关的技术,内容参考于《java多线程核心技术》与《java并发编程实战》等相关资料,希望站在巨人的肩膀上,再通过我的理解能让知识更加简单易懂。
目录认识cpu、核心与线程
java多线程系列(一)之java多线程技能
java多线程系列(二)之对象变量的并发访问
java多线程系列(三)之等待通知机制
java多线程系列(四)之ReentrantLock的使用
java多线程系列(五)之synchronized ReentrantLock volatile Atomic 原理分析
java多线程系列(六)之线程池原理及其使用
ReentrantLocak特性(对比synchronized)尝试获得锁
获取到锁的线程能够响应中断
ReentrantLock(重入锁) public class MyService { private Lock lock = new ReentrantLock(); public void testMethod() { lock.lock(); for (int i = 0; i < 5; i++) { System.out.println("ThreadName=" + Thread.currentThread().getName() + (" " + (i + 1))); } lock.unlock(); } }效果和synchronized一样,都可以同步执行,lock方法获得锁,unlock方法释放锁
await方法 public class MyService { private Lock lock = new ReentrantLock(); private Condition condition=lock.newCondition(); public void testMethod() { try { lock.lock(); System.out.println("开始wait"); condition.await(); for (int i = 0; i < 5; i++) { System.out.println("ThreadName=" + Thread.currentThread().getName() + (" " + (i + 1))); } } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } finally { lock.unlock(); } } }通过创建Condition对象来使线程wait,必须先执行lock.lock方法获得锁
signal方法 public void signal() { try { lock.lock(); condition.signal(); } finally { lock.unlock(); } }condition对象的signal方法可以唤醒wait线程
创建多个condition对象一个condition对象的signal(signalAll)方法和该对象的await方法是一一对应的,也就是一个condition对象的signal(signalAll)方法不能唤醒其他condition对象的await方法
ReentrantLock类可以唤醒指定条件的线程,而object的唤醒是随机的
Condition类和Object类Condition类的awiat方法和Object类的wait方法等效
Condition类的signal方法和Object类的notify方法等效
Condition类的signalAll方法和Object类的notifyAll方法等效
Lock的公平锁和非公平锁 Lock lock=new ReentrantLock(true);//公平锁 Lock lock=new ReentrantLock(false);//非公平锁公平锁指的是线程获取锁的顺序是按照加锁顺序来的,而非公平锁指的是抢锁机制,先lock的线程不一定先获得锁。
ReentrantLock类的方法getHoldCount() 查询当前线程保持此锁的次数,也就是执行此线程执行lock方法的次数
getQueueLength()返回正等待获取此锁的线程估计数,比如启动10个线程,1个线程获得锁,此时返回的是9
getWaitQueueLength(Condition condition)返回等待与此锁相关的给定条件的线程估计数。比如10个线程,用同一个condition对象,并且此时这10个线程都执行了condition对象的await方法,那么此时执行此方法返回10
hasWaiters(Condition condition)查询是否有线程等待与此锁有关的给定条件(condition),对于指定contidion对象,有多少线程执行了condition.await方法
hasQueuedThread(Thread thread)查询给定线程是否等待获取此锁
hasQueuedThreads()是否有线程等待此锁
isFair()该锁是否公平锁
isHeldByCurrentThread() 当前线程是否保持锁锁定,线程的执行lock方法的前后分别是false和true
isLock()此锁是否有任意线程占用
lockInterruptibly()如果当前线程未被中断,获取锁
tryLock()尝试获得锁,仅在调用时锁未被线程占用,获得锁
tryLock(long timeout TimeUnit unit)如果锁在给定等待时间内没有被另一个线程保持,则获取该锁
tryLock和lock和lockInterruptibly的区别tryLock能获得锁就返回true,不能就立即返回false,tryLock(long timeout,TimeUnit unit),可以增加时间限制,如果超过该时间段还没获得锁,返回false
lock能获得锁就返回true,不能的话一直等待获得锁
lock和lockInterruptibly,如果两个线程分别执行这两个方法,但此时中断这两个线程,前者不会抛出异常,而后者会抛出异常
读写锁