Java LinkedTransferQueue与实例
Java中的 LinkedTransferQueue 类是Java集合框架的一部分。它是在JDK 1.7中引入的,属于 java.util.concurrent 包。它实现了 TransferQueue ,并提供了一个基于链接节点的无界功能。LinkedTransferQueue中的元素以FIFO的顺序排列,头部指向在队列中时间最长的元素,尾部指向在队列中时间最短的元素。由于其异步性,size()会遍历整个集合,所以它不是一个O(1)时间操作。如果这个集合在遍历过程中被修改,它也可能给出不准确的大小。像addAll、removeAll、retainAll、containsAll、equals和toArray这样的批量操作不能保证原子地执行。例如,一个与addAll操作同时进行的迭代器可能只观察到一些被添加的元素。
LinkedTransferQueue已经使用了消息传递的应用。有两个方面,消息将从生产者线程传递给消费者线程。
- put(E e) : 如果生产者想要排队等待元素,而不需要等待消费者,就可以使用这个方法。然而,如果队列已满,它将等待,直到空间变得可用。
- transfer(E e) : 这个方法通常用于将一个元素转移到一个正在等待接收它的线程,如果没有线程在等待,那么它将等待,直到一个线程进入等待状态,一旦等待的线程到达,元素将被转移到其中。
LinkedTransferQueue的层次结构
它实现了 Serializable 、 **Iterable
声明 。
public class LinkedTransferQueue
这里, E 是这个集合所维护的元素的类型。
LinkedTransferQueue的构造函数
为了创建一个LinkedTransferQueue的实例,我们需要从 java.util.concurrent 包中导入它。
1.LinkedTransferQueue() : 这个构造函数用来构造一个空队列。
LinkedTransferQueue<E> ltq = new LinkedTransferQueue<E>()
**2.LinkedTransferQueue(Collection
LinkedTransferQueue<E> ltq = new LinkedTransferQueue<E>(Collection<E> c)
例子1: 说明Java中LinkedTransferQueue的示例程序
// Java Program Demonstrate LinkedTransferQueue
import java.util.concurrent.LinkedTransferQueue;
import java.util.*;
public class LinkedTransferQueueDemo {
public static void main(String[] args)
throws InterruptedException
{
// create object of LinkedTransferQueue
// using LinkedTransferQueue() constructor
LinkedTransferQueue<Integer> LTQ
= new LinkedTransferQueue<Integer>();
// Add numbers to end of LinkedTransferQueue
LTQ.add(7855642);
LTQ.add(35658786);
LTQ.add(5278367);
LTQ.add(74381793);
// print Queue
System.out.println("Linked Transfer Queue1: " + LTQ);
// create object of LinkedTransferQueue
// using LinkedTransferQueue(Collection c)
// constructor
LinkedTransferQueue<Integer> LTQ2
= new LinkedTransferQueue<Integer>(LTQ);
// print Queue
System.out.println("Linked Transfer Queue2: " + LTQ2);
}
}
输出
Linked Transfer Queue1: [7855642, 35658786, 5278367, 74381793]
Linked Transfer Queue2: [7855642, 35658786, 5278367, 74381793]
例2:
// Java code to illustrate
// methods of LinkedTransferQueue
import java.util.concurrent.LinkedTransferQueue;
import java.util.*;
public class LinkedTransferQueueDemo {
public static void main(String[] args)
throws InterruptedException
{
// create object of LinkedTransferQueue
LinkedTransferQueue<Integer> LTQ
= new LinkedTransferQueue<Integer>();
// Add numbers to end of LinkedTransferQueue
// using add() method
LTQ.add(7855642);
LTQ.add(35658786);
LTQ.add(5278367);
LTQ.add(74381793);
// prints the Queue
System.out.println("Linked Transfer Queue: " + LTQ);
// prints the size of Queue after removal
// using size() method
System.out.println("Size of Linked Transfer Queue: "
+ LTQ.size());
// removes the front element and prints it
// using poll() method
System.out.println("First element: " + LTQ.poll());
// prints the Queue
System.out.println("Linked Transfer Queue: " + LTQ);
// prints the size of Queue after removal
// using size() method
System.out.println("Size of Linked Transfer Queue: "
+ LTQ.size());
// Add numbers to end of LinkedTransferQueue
// using offer() method
LTQ.offer(20);
// prints the Queue
System.out.println("Linked Transfer Queue: " + LTQ);
// prints the size of Queue after removal
// using size() method
System.out.println("Size of Linked Transfer Queue: "
+ LTQ.size());
}
}
输出
Linked Transfer Queue: [7855642, 35658786, 5278367, 74381793]
Size of Linked Transfer Queue: 4
First element: 7855642
Linked Transfer Queue: [35658786, 5278367, 74381793]
Size of Linked Transfer Queue: 3
Linked Transfer Queue: [35658786, 5278367, 74381793, 20]
Size of Linked Transfer Queue: 4
基本操作
1.添加元素
LinkedTransferQueue提供了各种方法来添加或插入元素。它们是add(E e)、put(E e)、offer(E e)、transfer(E e)。add、put和offer方法并不关心其他线程是否在访问队列,而transfer()则是在等待一个或多个接收线程。
// Java Program Demonstrate adding
// elements to LinkedTransferQueue
import java.util.concurrent.*;
class AddingElementsExample {
public static void main(String[] args)
{
// Initializing the queue
LinkedTransferQueue<Integer> queue
= new LinkedTransferQueue<Integer>();
// Adding elements to this queue
for (int i = 10; i <= 14; i++)
queue.add(i);
// Add the element using offer() method
System.out.println("adding 15 "
+ queue.offer(15, 5, TimeUnit.SECONDS));
// Adding elements to this queue
for (int i = 16; i <= 20; i++)
queue.put(i);
// Printing the elements of the queue
System.out.println(
"The elements in the queue are:");
for (Integer i : queue)
System.out.print(i + " ");
System.out.println();
// create another queue to demonstrate transfer
// method
LinkedTransferQueue<String> g
= new LinkedTransferQueue<String>();
new Thread(new Runnable() {
public void run()
{
try {
System.out.println("Transferring"
+ " an element");
// Transfer a String element
// using transfer() method
g.transfer("is a computer"
+ " science portal.");
System.out.println(
"Element "
+ "transfer is complete");
}
catch (InterruptedException e1) {
System.out.println(e1);
}
catch (NullPointerException e2) {
System.out.println(e2);
}
}
})
.start();
try {
// Get the transferred element
System.out.println("Geeks for Geeks "
+ g.take());
}
catch (Exception e) {
System.out.println(e);
}
}
}
输出
adding 15 true
The elements in the queue are:
10 11 12 13 14 15 16 17 18 19 20
Transferring an element
Geeks for Geeks is a computer science portal.
Element transfer is complete
2.删除元素
LinkedTransferQueue提供的remove()方法是用来删除一个元素的,如果它存在于这个队列中。
// Java Program Demonstrate removing
// elements of LinkedTransferQueue
import java.util.concurrent.LinkedTransferQueue;
class RemoveElementsExample {
public static void main(String[] args)
{
// Initializing the queue
LinkedTransferQueue<Integer> queue
= new LinkedTransferQueue<Integer>();
// Adding elements to this queue
for (int i = 1; i <= 5; i++)
queue.add(i);
// Printing the elements of the queue
System.out.println(
"The elements in the queue are:");
for (Integer i : queue)
System.out.print(i + " ");
// remove() method will remove the specified
// element from the queue
queue.remove(1);
queue.remove(5);
// Printing the elements of the queue
System.out.println("\nRemaining elements in queue : ");
for (Integer i : queue)
System.out.print(i + " ");
}
}
输出
The elements in the queue are:
1 2 3 4 5
Remaining elements in queue :
2 3 4
3.迭代
LinkedTransferQueue的iterator()方法被用来以适当的顺序返回这个队列中的元素的一个迭代器。
// Java Program Demonstrate iterating
// over LinkedTransferQueue
import java.util.Iterator;
import java.util.concurrent.LinkedTransferQueue;
class LinkedTransferQueueIteratorExample {
public static void main(String[] args)
{
// Initializing the queue
LinkedTransferQueue<String> queue
= new LinkedTransferQueue<String>();
// Adding elements to this queue
queue.add("Gfg");
queue.add("is");
queue.add("fun!!");
// Returns an iterator over the elements
Iterator<String> iterator = queue.iterator();
// Printing the elements of the queue
while (iterator.hasNext())
System.out.print(iterator.next() + " ");
}
}
输出
Gfg is fun!!
LinkedTransferQueue的方法
方法 | 描述 |
---|---|
add(E e) | 在这个队列的尾部插入指定的元素。 |
contains(Object o) | 如果这个队列包含指定的元素,返回true。 |
drainTo(Collection super E> c) | 从这个队列中删除所有可用的元素,并将它们添加到给定的集合中。 drainTo(Collection super E> c, int maxElements) | 从这个队列中最多删除给定数量的可用元素,并将它们添加到给定的集合中。 forEach(Consumer super E> action) | 对Iterable的每个元素执行给定的动作,直到所有的元素都被处理完,或者该动作抛出一个异常。 isEmpty() | 如果这个队列不包含任何元素,返回true。 iterator() | 返回这个队列中的元素的迭代器,其顺序是正确的。 offer(E e) | 在这个队列的尾部插入指定的元素。 offer(E e, long timeout, TimeUnit unit) | 在这个队列的尾部插入指定的元素。 put(E e) | 在这个队列的尾部插入指定的元素。 remainingCapacity() | 总是返回Integer.MAX_VALUE,因为LinkedTransferQueue不受容量限制。 remove(Object o) | 从这个队列中删除指定元素的一个实例,如果它存在的话。 removeAll(Collection> c) |
删除此集合中也包含在指定集合中的所有元素(可选操作)。 |
removeIf(Predicate super E> filter) | 删除此集合中满足给定谓词的所有元素。 retainAll(Collection> c) |
只保留此集合中包含在指定集合中的元素(可选操作)。 |
size() | 返回这个队列中元素的数量。 |
spliterator() | 返回这个队列中的元素的Spliterator。 |
toArray() | 返回一个包含该队列中所有元素的数组,并以适当的顺序排列。 |
toArray(T[] a) | 返回一个包含此队列中所有元素的数组,并以适当的顺序排列;返回的数组的运行时类型是指定数组的类型。 |
transfer(E e) | 将元素转移到消费者那里,如果有必要,可以等待。 |
tryTransfer(E e) | 如果可能的话,立即将元素转移给等待的消费者。 |
tryTransfer(E e, long timeout, TimeUnit unit) | 如果有可能在超时之前将元素转移给消费者。 |
类java.util.AbstractQueue中声明的方法
方法 | 描述 |
---|---|
addAll(Collection extends E> c) | 将指定集合中的所有元素添加到这个队列中。 clear() | 从这个队列中删除所有的元素。 element() | 检索,但不删除这个队列的头部。 remove() | 检索并删除此队列的头部。 ### java.util.AbstractCollection类中声明的方法 方法 | 描述 |
如果这个集合包含指定集合中的所有元素,则返回true。 |
toString() | 返回这个集合的一个字符串表示。 |
在接口java.util.concurrent.BlockingQueue中声明的方法
方法 | 描述 |
---|---|
poll(long timeout, TimeUnit unit) | 检索并删除这个队列的头部,如果有必要,可以等待指定的等待时间,让元素变得可用。 |
take() | 检索并删除这个队列的头部,如果需要的话,等待一个元素变得可用。 |
java.util.Collection接口中声明的方法
方法 | 描述 |
---|---|
addAll(Collection extends E> c) | 将指定集合中的所有元素添加到这个集合中(可选操作)。 clear() | 从这个集合中删除所有的元素(可选操作)。 containsAll(Collection> c) |
如果这个集合包含了指定集合中的所有元素,返回true。 |
equals(Object o) | 将指定的对象与这个集合进行比较,看是否相等。 |
hashCode() | 返回这个集合的哈希代码值。 |
parallelStream() | 返回一个以该集合为源的可能的并行流。 |
stream() | 返回一个以这个集合为源的顺序流。 |
toArray(IntFunction<T[]> generator) | 返回一个包含此集合中所有元素的数组,使用提供的生成器函数来分配返回的数组。 |
java.util.Queue中声明的方法
方法 | 描述 |
---|---|
element() | 检索,但不删除这个队列的头部。 |
peek() | 检索但不删除这个队列的头部,如果这个队列是空的,则返回null。 |
poll() | 检索并删除这个队列的头部,如果这个队列是空的,则返回null。 |
remove() | 检索并删除该队列的头部。 |
java.util.concurrent.TransferQueue接口中声明的方法
方法 | 描述 |
---|---|
getWaitingConsumerCount() | 返回等待通过BlockingQueue.take()或定时轮询接收元素的消费者的估计数量。 |
hasWaitingConsumer() | 如果至少有一个消费者在等待通过BlockingQueue.take()或定时轮询接收一个元素,则返回true。 |
参考: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/LinkedTransferQueue.html