当前位置: 首页> 房产> 建材 > erp系统哪家做得好_中企动力科技_淘宝指数查询官网手机版_搜客通

erp系统哪家做得好_中企动力科技_淘宝指数查询官网手机版_搜客通

时间:2025/7/10 11:12:49来源:https://blog.csdn.net/qq_41478243/article/details/146190752 浏览次数:1次
erp系统哪家做得好_中企动力科技_淘宝指数查询官网手机版_搜客通

引入

在什么是阻塞队列一文中,我们提到了BlockingQueue 接口常见的和常用的实现类包括ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、PriorityBlockingQueue,以及 DelayQueue。

这些实现类都被放在了 J.U.C 包中,我们来看看它们都有什么特点。

ArrayBlockingQueue

还是老样子,先看看源码注释:

A bounded blocking queue backed by an array. This queue orders elements FIFO (first-in-first-out). The head of the queue is that element that has been on the queue the longest time. The tail of the queue is that element that has been on the queue the shortest time. New elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue.
This is a classic "bounded buffer", in which a fixed-sized array holds elements inserted by producers and extracted by consumers. Once created, the capacity cannot be changed. Attempts to put an element into a full queue will result in the operation blocking; attempts to take an element from an empty queue will similarly block.
This class supports an optional fairness policy for ordering waiting producer and consumer threads. By default, this ordering is not guaranteed. However, a queue constructed with fairness set to true grants threads access in FIFO order. Fairness generally decreases throughput but reduces variability and avoids starvation.
This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces.
This class is a member of the Java Collections Framework.

翻译:

一个由数组支持的有界阻塞队列。此队列按先进先出(FIFO)的顺序排列元素。队列的头部是在队列中存在时间最长的元素。队列的尾部是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列的检索操作则从队列的头部获取元素。
这是一个经典的 “有界缓冲区”,在其中一个固定大小的数组保存由生产者插入、消费者提取的元素。一旦创建,其容量就无法更改。尝试将元素放入已满的队列中会导致操作阻塞;尝试从空队列中取出元素也会类似地阻塞。
此类支持一种可选的公平策略,用于对等待的生产者线程和消费者线程进行排序。默认情况下,不保证这种排序。然而,创建时将公平性设置为 true 的队列会按先进先出的顺序授予线程访问权限。公平性通常会降低吞吐量,但会减少可变性并避免饥饿现象。
此类及其迭代器实现了Collection接口和Iterator接口的所有可选方法。
此类是 Java 集合框架的成员之一。

ArrayBlockingQueue 可以说是最基础的实现类,它是典型的有界队列,其内部是用数组存储元素的,利用 ReentrantLock 实现线程安全。

我们在创建它的时候就需要指定它的容量,之后也不可以再扩容了,在构造函数中我们还可以指定是否是公平的,代码如下:

    /*** 创建一个具有给定(固定)容量和指定访问策略的 {@code ArrayBlockingQueue}。** @param capacity 此队列的容量* @param fair 如果为 {@code true},则以 FIFO 顺序处理因插入或移除操作而阻塞的线程的队列访问;*             如果为 {@code false},则访问顺序未指定。* @throws IllegalArgumentException 如果 {@code capacity} 小于 1。*/public ArrayBlockingQueue(int capacity, boolean fair) {// 检查容量是否小于等于 0,如果是则抛出 IllegalArgumentException 异常if (capacity <= 0)throw new IllegalArgumentException();// 初始化队列存储元素的数组,数组大小为指定的容量this.items = new Object[capacity];// 初始化重入锁,根据 fair 参数决定是否使用公平锁lock = new ReentrantLock(fair);// 创建一个与锁关联的条件对象,用于表示队列不为空的条件notEmpty = lock.newCondition();// 创建一个与锁关联的条件对象,用于表示队列未满的条件notFull =  lock.newCondition();}

第一个参数是容量,第二个参数是是否公平。

正如 ReentrantLock 一样,如果ArrayBlockingQueue 被设置为非公平的,那么就存在插队的可能;如果设置为公平的,那么等待了最长时间的线程会被优先处理,其他线程不允许插队,不过这样的公平策略同时会带来一定的性能损耗,因为非公平的吞吐量通常会高于公平的情况。

LinkedBlockingQueue

对应源码注释如下:

An optionally-bounded blocking queue based on linked nodes. This queue orders elements FIFO (first-in-first-out). The head of the queue is that element that has been on the queue the longest time. The tail of the queue is that element that has been on the queue the shortest time. New elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue. Linked queues typically have higher throughput than array-based queues but less predictable performance in most concurrent applications.
The optional capacity bound constructor argument serves as a way to prevent excessive queue expansion. The capacity, if unspecified, is equal to Integer. MAX_VALUE. Linked nodes are dynamically created upon each insertion unless this would bring the queue above capacity.
This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces.
This class is a member of the Java Collections Framework.

翻译:

这是一个基于链表节点、容量可选有界的阻塞队列。该队列按照先进先出(FIFO)的规则对元素进行排序。队列头部的元素是在队列中存在时间最久的,而队列尾部的元素则是入队时间最短的。新元素会被插入到队列尾部,而从队列中检索元素的操作则是从队列头部获取元素。在大多数并发应用场景中,链表队列通常比基于数组的队列吞吐量更高,但性能的可预测性较差。
构造函数中可选择指定容量上限,这是为了防止队列过度扩张。如果未指定容量,默认容量为Integer.MAX_VALUE。除非插入操作会使队列超出容量限制,否则每次插入元素时都会动态创建链表节点。
这个类及其迭代器实现了Collection和Iterator接口中的所有可选方法。
该类是 Java 集合框架的成员之一。

正如名字所示,这是一个内部用链表实现的 BlockingQueue。如果我们不指定它的初始容量,那么它容量默认就为整型的最大值 Integer.MAX_VALUE,由于这个数非常大,我们通常不可能放入这么多的数据,所以 LinkedBlockingQueue 也被称作无界队列,代表它几乎没有界限。

SynchronousQueue

对应源码注释如下:

A blocking queue in which each insert operation must wait for a corresponding remove operation by another thread, and vice versa. A synchronous queue does not have any internal capacity, not even a capacity of one. You cannot peek at a synchronous queue because an element is only present when you try to remove it; you cannot insert an element (using any method) unless another thread is trying to remove it; you cannot iterate as there is nothing to iterate. The head of the queue is the element that the first queued inserting thread is trying to add to the queue; if there is no such queued thread then no element is available for removal and poll() will return null. For purposes of other Collection methods (for example contains), a SynchronousQueue acts as an empty collection. This queue does not permit null elements.
Synchronous queues are similar to rendezvous channels used in CSP and Ada. They are well suited for handoff designs, in which an object running in one thread must sync up with an object running in another thread in order to hand it some information, event, or task.
This class supports an optional fairness policy for ordering waiting producer and consumer threads. By default, this ordering is not guaranteed. However, a queue constructed with fairness set to true grants threads access in FIFO order.
This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces.
This class is a member of the Java Collections Framework.

翻译:

这是一种阻塞队列,在该队列中,每个插入操作都必须等待另一个线程执行相应的移除操作,反之亦然。同步队列没有任何内部容量,甚至连容纳一个元素的容量都没有。你无法查看同步队列中的元素,因为只有当你尝试移除元素时,元素才会存在;除非有另一个线程正试图移除元素,否则你无法插入元素(使用任何方法都不行);由于没有可迭代的内容,所以也无法进行迭代操作。队列的头部元素是第一个排队等待插入的线程试图添加到队列中的元素;如果没有这样排队的线程,那么就没有元素可供移除,poll()方法将返回null。就其他Collection方法(例如contains)而言,SynchronousQueue表现得像一个空集合。该队列不允许包含null元素。
同步队列类似于在通信顺序进程(CSP)和 Ada 语言中使用的会合通道。它们非常适合用于交接设计,在这种设计中,在一个线程中运行的对象必须与在另一个线程中运行的对象进行同步,以便传递某些信息、事件或任务。
此类支持一种可选的公平策略,用于对等待的生产者线程和消费者线程进行排序。默认情况下,不保证这种排序。然而,创建时将公平性设置为true的队列会按先进先出的顺序授予线程访问权限。
此类及其迭代器实现了Collection接口和Iterator接口的所有可选方法。
此类是 Java 集合框架的成员之一。

SynchronousQueue 最特别的地方在于,它的容量为 0,所以没有一个地方来暂存元素,导致每次取数据都要先阻塞,直到有数据被放入;同理,每次放数据的时候也会阻塞,直到有消费者来取。

需要注意的是,SynchronousQueue 的容量不是 1 而是 0,因为 SynchronousQueue 不需要去持有元素,它所做的就是直接传递(direct handoff)。由于每当需要传递的时候 SynchronousQueue 会把元素直接从生产者传给消费者,在此期间并不需要做存储,所以如果运用得当,它的效率是很高的。

另外,由于它的容量为 0,所以相比于一般的阻塞队列,SynchronousQueue 的很多方法的实现是很有意思的。

例子

SynchronousQueue 的 peek 方法永远返回 null,代码如下:

    /*** 查看队列头部的元素,但不移除它。* 由于{@code SynchronousQueue}没有内部容量,不主动等待的情况下不会返回元素,* 因此该方法总是返回{@code null}。** @return 总是返回{@code null}*/public E peek() {return null;}

因为 peek 方法的含义是取出头结点,但是 SynchronousQueue 的容量是 0,所以连头结点都没有,peek 方法也就没有意义,所以始终返回 null。同理,element 始终会抛出 NoSuchElementException异常。
而 SynchronousQueue 的 size 方法始终返回 0,因为它内部并没有容量,代码如下:

    /*** 始终返回零。* 一个 {@code SynchronousQueue} 没有内部容量。** @return 零*/public int size() {return 0;}

同理,isEmpty 方法始终返回 true:

    /*** 检查队列是否为空。* 由于{@code SynchronousQueue}没有内部容量,所以该方法总是返回{@code true}。** @return 总是返回{@code true},表示队列是空的。*/public boolean isEmpty() {return true;}

因为它始终都是空的。

PriorityBlockingQueue

前面我们所说的 ArrayBlockingQueue 和 LinkedBlockingQueue 都是采用先进先出的顺序进行排序,可是如果有的时候我们需要自定义排序怎么办呢?

这时就需要使用 PriorityBlockingQueue,它的源码注释如下:

An unbounded blocking queue that uses the same ordering rules as class PriorityQueue and supplies blocking retrieval operations. While this queue is logically unbounded, attempted additions may fail due to resource exhaustion (causing OutOfMemoryError). This class does not permit null elements. A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so results in ClassCastException).
This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces. The Iterator provided in method iterator() is not guaranteed to traverse the elements of the PriorityBlockingQueue in any particular order. If you need ordered traversal, consider using Arrays. sort(pq. toArray()). Also, method drainTo can be used to remove some or all elements in priority order and place them in another collection.
Operations on this class make no guarantees about the ordering of elements with equal priority. If you need to enforce an ordering, you can define custom classes or comparators that use a secondary key to break ties in primary priority values. For example, here is a class that applies first-in-first-out tie-breaking to comparable elements. To use it, you would insert a new FIFOEntry(anEntry) instead of a plain entry object.

class FIFOEntry<E extends Comparable<? super E>> implements Comparable<FIFOEntry<E>> {   static final AtomicLong seq = new AtomicLong(0);   final long seqNum;   final E entry;   public FIFOEntry(E entry) {    seqNum = seq.getAndIncrement();  this.entry = entry;   }  public E getEntry() { return entry; } public int compareTo(FIFOEntry<E> other) {  int res = entry. compareTo(other. entry); if (res == 0 && other. entry != this.entry)    res = (seqNum < other. seqNum ? -1 : 1);   return res;  } 
}

This class is a member of the Java Collections Framework.

翻译:

这是一个无界阻塞队列,它采用与PriorityQueue类相同的排序规则,并提供阻塞式的检索操作。虽然这个队列在逻辑上是无界的,但由于资源耗尽(会导致OutOfMemoryError),尝试添加元素的操作仍可能失败。此类不允许包含null元素。依赖自然排序的优先队列同样不允许插入不可比较的对象(否则会引发ClassCastException)。
此类及其迭代器实现了Collection接口和Iterator接口的所有可选方法。iterator()方法所提供的迭代器并不保证以任何特定顺序遍历PriorityBlockingQueue中的元素。若你需要有序遍历,可考虑使用Arrays.sort(pq.toArray())。此外,drainTo方法可用于按优先级顺序移除部分或全部元素,并将它们放入另一个集合中。
此类的操作并不能保证具有相同优先级的元素的排序顺序。如果你需要强制排序,可以定义自定义类或比较器,利用次要键来区分主要优先级值相同的元素。例如,下面是一个类,它对可比较的元素采用先进先出的方式来处理优先级相同的情况。若要使用该类,你需插入一个新的FIFOEntry(anEntry),而非普通的条目对象。

/*** 实现一个支持FIFO(先进先出)顺序的条目类。* 该类用于在需要按插入顺序排序的场景中,确保具有相同排序键的元素按插入顺序排列。** @param <E> 条目的类型,必须实现Comparable接口。*/
class FIFOEntry<E extends Comparable<? super E>> implements Comparable<FIFOEntry<E>> {// 静态原子计数器,用于为每个条目分配唯一的序列号static final AtomicLong seq = new AtomicLong(0);// 条目的序列号,用于确保FIFO顺序final long seqNum;// 实际的条目内容final E entry;/*** 构造函数,创建一个新的FIFOEntry实例。** @param entry 实际的条目内容。*/public FIFOEntry(E entry) {// 获取当前的序列号并自增seqNum = seq.getAndIncrement();this.entry = entry;}/*** 获取实际的条目内容。** @return 实际的条目内容。*/public E getEntry() { return entry; }/*** 比较两个FIFOEntry实例的顺序。* 首先比较条目的自然顺序,如果相等,则比较序列号以确保FIFO顺序。** @param other 要比较的另一个FIFOEntry实例。* @return 如果当前实例小于另一个实例,则返回负数;如果相等,则返回0;如果大于,则返回正数。*/public int compareTo(FIFOEntry<E> other) {// 比较条目内容的自然顺序int res = entry.compareTo(other.entry);// 如果条目内容相等且不是同一个对象,则比较序列号if (res == 0 && other.entry != this.entry)res = (seqNum < other.seqNum ? -1 : 1);return res;}
}

此类是Java集合框架的成员之一。

PriorityBlockingQueue 是一个支持优先级的无界阻塞队列,可以通过自定义类实现 compareTo() 方法来指定元素排序规则,或者初始化时通过构造器参数 Comparator 来指定排序规则。同时,插入队列的对象必须是可比较大小的,也就是 Comparable 的,否则会抛出 ClassCastException 异常。

它的 take 方法在队列为空的时候会阻塞,但是正因为它是无界队列,而且会自动扩容,所以它的队列永远不会满,所以它的 put 方法永远不会阻塞,添加操作始终都会成功,也正因为如此,它的成员变量里只有一个 Condition:

    /*** 当队列不为空时,用于唤醒等待的线程的条件对象。* 此条件与锁对象 {@link #lock} 关联,确保在操作队列时线程安全。* 当队列中有元素时,会调用该条件的 signal 方法来唤醒等待的线程。*/private final Condition notEmpty;

这和之前的 ArrayBlockingQueue 拥有两个 Condition(分别是 notEmpty 和 notFull)形成了鲜明的对比,我们的 PriorityBlockingQueue 不需要 notFull,因为它永远都不会满,真是“有空间就可以任性”。

DelayQueue

对应源码注释如下:

An unbounded blocking queue of Delayed elements, in which an element can only be taken when its delay has expired. The head of the queue is that Delayed element whose delay expired furthest in the past. If no delay has expired there is no head and poll will return null. Expiration occurs when an element's getDelay(TimeUnit. NANOSECONDS) method returns a value less than or equal to zero. Even though unexpired elements cannot be removed using take or poll, they are otherwise treated as normal elements. For example, the size method returns the count of both expired and unexpired elements. This queue does not permit null elements.
This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces. The Iterator provided in method iterator() is not guaranteed to traverse the elements of the DelayQueue in any particular order.
This class is a member of the Java Collections Framework.

翻译:

这是一个用于存放延迟元素的无界阻塞队列,队列中的元素只有在其延迟时间到期后才能被取出。队列的头部是延迟时间最早到期的延迟元素。如果没有元素的延迟时间到期,那么队列就没有头部元素,此时调用 poll() 方法将返回 null。当元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回的值小于或等于零时,即认为该元素的延迟时间已到期。尽管无法使用 take() 或 poll() 方法移除未到期的元素,但在其他方面,这些未到期元素会被视为普通元素。例如,size() 方法会返回已到期和未到期元素的总数。此队列不允许存放 null 元素。
此类及其迭代器实现了 Collection 接口和 Iterator 接口的所有可选方法。iterator() 方法提供的迭代器并不保证会以任何特定顺序遍历 DelayQueue 中的元素。
此类是 Java 集合框架的成员之一。

DelayQueue 这个队列比较特殊,具有“延迟”的功能。我们可以设定让队列中的任务延迟多久之后执行,比如 10 秒钟之后执行,这在例如“30 分钟后未付款自动取消订单”等需要延迟执行的场景中被大量使用。

它是无界队列,放入的元素必须实现 Delayed 接口,而 Delayed 接口又继承了 Comparable 接口,所以自然就拥有了比较和排序的能力,Delayed的源码注释如下:

A mix-in style interface for marking objects that should be acted upon after a given delay.
An implementation of this interface must define a compareTo method that provides an ordering consistent with its getDelay method.

翻译:

这是一种混合风格的接口,用于标记那些需要在给定延迟时间后执行相应操作的对象。
实现此接口的类必须定义一个 compareTo 方法,该方法所提供的排序规则要与 getDelay 方法保持一致。

对应源码如下:

/*** 一个混合风格的接口,用于标记那些应该在给定延迟后执行操作的对象。* 实现此接口的类必须定义一个 {@code compareTo} 方法,该方法的排序规则应与 {@code getDelay} 方法一致。*/
public interface Delayed extends Comparable<Delayed> {/*** 返回此对象与给定时间单位相关的剩余延迟时间。** @param unit 时间单位* @return 剩余延迟时间;零或负值表示延迟已经过去*/long getDelay(TimeUnit unit);
}

可以看出这个 Delayed 接口继承自 Comparable,里面有一个需要实现的方法,就是  getDelay。这里的 getDelay 方法返回的是“还剩下多长的延迟时间才会被执行”,如果返回 0 或者负数则代表任务已过期。

元素会根据延迟时间的长短被放到队列的不同位置,越靠近队列头代表越早过期。

DelayQueue 内部使用了 PriorityQueue 的能力来进行排序,而不是自己从头编写,我们在工作中可以学习这种思想,对已有的功能进行复用,不但可以减少开发量,同时避免了“重复造轮子”,更重要的是,对学到的知识进行合理的运用,做到触类旁通。

关键字:erp系统哪家做得好_中企动力科技_淘宝指数查询官网手机版_搜客通

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: