AbstractQueueSynchronizer

1.AbstractQueuedSynchronizer(以下简称AQS)是Java并发包提供的一个同步基础机制,是并发包中实现Lock和其他同步机制(如:Semaphore、CountDownLatch和FutureTask等)的基础。

2.AQS内部包含一个FIFO的同步等待队列,简单的说,没有成功获取控制权的线程会在这个队列中等待。

3.AQS内部管理了一个原子的int域作为内部状态信息,并提供了一些方法来访问该域,基于AQS实现的同步机制可以按自己的需要来灵活使用这个int域, 比如:ReentrantLock用它记录锁重入次数;CountDownLatch用它表示内部的count;FutureTask用它表示任务运行状 态(Running,Ran和Cancelled);Semaphore用它表示许可数量。

4.AQS提供了独占和共享两种模式。在独占模式下,当一个线程获取了AQS的控制权,其他线程获取控制权的操作就会失败;但在共享模式下,其他线程 的获取控制权操作就可能成功。并发包中的同步机制如ReentrantLock就是典型的独占模式,Semaphore是共享模式;也有同时使用两种模式 的同步机制,如ReentrantReadWriteLock。  AQS内部提供了一个ConditionObject类来支持独占模式下的(锁)条件,这个条件的功能与Object的wait和notify/notifyAll的功能类似,但更加明确和易用。

状态位+队列

ReentrantLock

1.与Synchronized相比较而言,ReentrantLock有以下优势:支持公平/非公平锁、支持可中断的锁、支持非阻塞的tryLock(可超时)、支持锁条件、可跨代码块使用(一个地方加锁,另一个地方解锁),总之比Synchronized更加灵活

ReentrantReadWriteLock

  • ReentrantReadWriteLock提供了读写锁的机制,读锁使用AQS的共享模式,写锁使用独占模式。
  • ReentrantReadWriteLock也支持公平/非公平锁。
  • ReentrantReadWriteLock的写锁会阻塞读锁和写锁,读锁只会阻塞写锁。
  • ReentrantReadWriteLock的写锁可以降级为读锁,但读锁不能升级为写锁。

CountDownLatch

  • CountDownLatch称为闭锁。可以让一个或多个线程等待另外一个或多个线程执行完毕后再执行。
  • CountDownLatch也是基于AQS构建,使用共享模式。

  

Semaphore

   是一种基于计数的信号量,管理了一组许可。线程可以申请许可,当信号量中有许可时,线程申请成功,拿走一个许可;没有许可时, 线程阻塞等待其他线程用完了许可,归还给信号量。这个许可不是真正的许可(比如凭证),只是一个计数,线程也不会真正使用这些许可。

  • Semaphore一般用来构建一些对象池,资源池之类的,比如数据库连接池。
  • 可以创建一个count为1的Semaphore作为一种类似互斥锁的机制,也叫二元信号量,表示两种互斥状态。但和Lock有些区别,Lock只能又获取锁的线程来释放锁,而Semaphore允许其他线程来做释放动作。
  • Semaphore也支持公平和非公平策略。

ArrayBlockingQueue

  • ArrayBlockingQueue是一种基于数组实现的有界的阻塞队列。队列中的元素遵循先入先出(FIFO)的规则。新元素插入到队列的尾部,从队列头部取出元素。
  • 和普通队列有所不同,该队列支持阻塞操作。比如从空队列中取元素,会导致当前线程阻塞,直到其他线程将元素放入队列;将元素插入已经满的队列,同样会导致当前线程阻塞,直到其他线程从队列中取出元素。
  • ArrayBlockingQueue也支持公平和非公平策略(针对队列中元素的存取线程,也可认为是元素的生产者和消费者)。

 不能为null insert extract

LinkedBlokingQueue

LinkedBlockingQueue是一种基于单向链表实现的有界的(可选的,不指定默认int最大值)阻塞队列。队列中的元素遵循先入先出(FIFO)的规则。新元素插入到队列的尾部,从队列头部取出元素。

ThreadPoolExecutor

ThreadPoolExecutor是JUC包中提供的线程池,使用ThreadPoolExecutor的好处一方面是能重用线程资源,避免重复创建 线程带来的开销;另一方面是ThreadPoolExecutor提供了内部资源(线程、任务)的管理功能,方便我们监控线程池工作状态。

4个状态:

  1.  static final int RUNNING    = 0; //表示正在运行。会接受新任务,并会处理任务队列中的任务。  
  2.     static final int SHUTDOWN   = 1; //表示已经关闭。不接受新任务,但仍然会处理任务队列中的任务。  
  3.     static final int STOP       = 2; //表示已经停止。不接受新任务,不处理任务队列中的任务,会中断正在执行的任务。  
  4.     static final int TERMINATED = 3; //在STOP的基础上,在加上所有的任务都已经结束。

一个任务队列,一个工作类集合,一些状态数据还有一个拒绝任务处理器。

execute,执行逻辑,

shutdown

shutdownnow

    1. * 1. 运行状态设置为STOP。 
    2.         * 2. 中断所有的工作线程,不仅仅是空闲的工作线程。 
    3.         * 3. 清空任务队列,并返回任务队列中的任务。

Woker类 ,poll,take

  1. Runnable getTask() {  
  2.     for (;;) {  
  3.         try {  
  4.             int state = runState;  
  5.             if (state > SHUTDOWN)  
  6.                 return null; // 线程池已经停止或终止,获取不到任务。  
  7.             Runnable r;  
  8.             if (state == SHUTDOWN)   
  9.                 r = workQueue.poll(); // 如果线程池已经关闭,还可以从任务队列中取任务。  
  10.             else if (poolSize > corePoolSize || allowCoreThreadTimeOut)  
  11.                 /* 
  12.                  * 如果当前线程数量多于核心线程数量或者允许核心线程超时, 
  13.                  * 才会调用带超时的poll方法,如果超时时间内无法获取任务 
  14.                  * 那么当前worker后继就会被干掉了。 
  15.                  */  
  16.                 r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);  
  17.             else  
  18.                 r = workQueue.take(); //否则,调用take方法,阻塞直到有任务可以获取。  
  19.             if (r != null)  
  20.                 return r;   
  21.             //如果没有获取到任务,检测一下当前worker是否可以退出。  
  22.             if (workerCanExit()) {  
  23.                 if (runState >= SHUTDOWN)   
  24.                     interruptIdleWorkers(); // 如果线程池已经关闭,中断空闲的worker。  
  25.                 return null;  
  26.             }  
  27.             // Else retry  
  28.         } catch (InterruptedException ie) {  
  29.             // On interruption, re-check runState  
  30.         }  
  31.     }  
原文地址:https://www.cnblogs.com/lelouchKOP/p/5792746.html