LinkedTransferQueue在Java中的应用与例子

LinkedTransferQueue在Java中的应用与例子

Java Collection Framework中, LinkedTransferQueue 类是Java JDK 1.7中引入的一部分,它属于 java.util.concurrent 包。它实现了 TransferQueue 并基于链接节点提供了无界的功能。LinkedTransferQueue中的元素按FIFO顺序排序,头指针指向最长时间在队列中的元素,尾指针指向最短时间在队列中的元素。由于其异步性质,size()遍历整个集合,因此它不是O(1)的时间操作。如果在遍历期间修改这个集合,它也可能给出不准确的大小。addAll、removeAll、retainAll、containsAll、equals和toArray等批量操作不保证以原子方式执行。例如,与addAll操作并发执行的iterator可能只观察到所添加的元素的一些。

LinkedTransferQueue已经被用于消息传递应用程序。从生产者线程向消费者线程传递消息的方式有两个方面。

  1. put(E e):如果生产者要将元素入队而不等待消费者,则使用此方法。但是,如果队列已满,则等待空间可用。
  2. transfer(E e):此方法通常用于将元素传递到等待接收它的线程,如果没有线程在等待,则它将等待,直到线程处于等待状态,一旦等待的线程到达,元素将传递到该线程。

LinkedTransferQueue的层次结构

LinkedTransferQueue在Java中的应用与例子

它实现了 SerializableIterable Collection BlockingQueue TransferQueue Queue 接口,并扩展了AbstractQueue和AbstractCollection类。

声明:

public class LinkedTransferQueue<E> extends AbstractQueue<E> implements TransferQueue<E>, Serializable

在这里, E 是此集合维护的元素类型。

LinkedTransferQueue的构造函数

为了创建LinkedTransferQueue的实例,我们需要从 java.util.concurrent 包中导入它。

1. LinkedTransferQueue() :此构造函数用于构造空队列。

LinkedTransferQueue<E> ltq = new LinkedTransferQueue<E>();

2.LinkedTransferQueue(Collection c):此构造函数用于使用传递的Collection中的元素构造队列。

LinkedTransferQueue<E> ltq = new LinkedTransferQueue<E>(Collection<E> c);

例1: 演示Java中的LinkedTransferQueue的样例程序

// Java程序展示LinkedTransferQueue
  
import java.util.concurrent.LinkedTransferQueue;
import java.util.*;
  
public class LinkedTransferQueueDemo {
    public static void main(String[] args)
        throws InterruptedException
    {
        //使用LinkedTransferQueue()构造函数创建LinkedTransferQueue对象
        LinkedTransferQueue<Integer> LTQ
            = new LinkedTransferQueue<Integer>();
  
        //将数字添加到LinkedTransferQueue末尾
        LTQ.add(7855642);
        LTQ.add(35658786);
        LTQ.add(5278367);
        LTQ.add(74381793);
  
        //打印队列
        System.out.println("Linked Transfer Queue1: " + LTQ);
  
        //使用LinkedTransferQueue(Collection c)构造函数创建LinkedTransferQueue对象
        LinkedTransferQueue<Integer> LTQ2
            = new LinkedTransferQueue<Integer>(LTQ);
  
        //打印队列
        System.out.println("Linked Transfer Queue2: " + LTQ2);
    }
}

输出结果

Linked Transfer Queue1: [7855642, 35658786, 5278367, 74381793]
Linked Transfer Queue2: [7855642, 35658786, 5278367, 74381793]

示例2:

// Java代码演示LinkedTransferQueue的方法
  
import java.util.concurrent.LinkedTransferQueue;
import java.util.*;
  
public class LinkedTransferQueueDemo {
    public static void main(String[] args)
        throws InterruptedException
    {
  
        //创建LinkedTransferQueue对象
        LinkedTransferQueue<Integer> LTQ
            = new LinkedTransferQueue<Integer>();
  
        //使用add()方法将数字添加到LinkedTransferQueue末尾
        LTQ.add(7855642);
        LTQ.add(35658786);
        LTQ.add(5278367);
        LTQ.add(74381793);
  
        //打印队列
        System.out.println("Linked Transfer Queue: " + LTQ);
  
        //使用size()方法取出队首元素并打印
        System.out.println("Size of Linked Transfer Queue: "
                           + LTQ.size());
  
        //使用poll()方法将元素从队列中移除并打印
        System.out.println("First element: " + LTQ.poll());
  
        //打印队列
        System.out.println("Linked Transfer Queue: " + LTQ);
  
        //使用size()方法获取队列大小并打印
        System.out.println("Size of Linked Transfer Queue: "
                           + LTQ.size());
  
        //使用offer()方法将数字添加到LinkedTransferQueue末尾
        LTQ.offer(20);
  
        //打印队列
        System.out.println("Linked Transfer Queue: " + LTQ);
  
        //使用size()方法获取队列大小并打印
        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
队列中的元素为:
10 11 12 13 14 15 16 17 18 19 20 
转移一个元素
Geeks for Geeks 是一个计算机科学门户网站。
元素转移完成

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 + " ");
    }
}

输出:

队列中的元素为:
1 2 3 4 5
队列中剩余的元素为:
2 3 4 

3. 迭代

LinkedTransferQueue的iterator()方法用于按正确顺序在此队列中返回一个迭代器的元素。

//Java程序演示LinkedTransferQueue的迭代
  
import java.util.Iterator;
import java.util.concurrent.LinkedTransferQueue;
  
class LinkedTransferQueueIteratorExample {
    public static void main(String[] args)
    {
  
        //初始化队列
        LinkedTransferQueue<String> queue
            = new LinkedTransferQueue<String>();
  
        //向此队列添加元素
        queue.add("Gfg");
        queue.add("is");
        queue.add("fun!!");
  
        //返回一个迭代器的元素
        Iterator<String> iterator = queue.iterator();
  
        //打印队列的元素
        while (iterator.hasNext())
            System.out.print(iterator.next() + " ");
    }
}

输出

Gfg is fun!! 

LinkedTransferQueue的方法

方法 描述
add​(E e) 在此队列的末尾插入指定的元素。
contains​(Object o) 如果此队列包含指定的元素,则返回 true。
drainTo​(Collection c) | 移除此队列中的所有可用元素,并将它们添加到给定的集合中。
drainTo​(Collection c, int maxElements) | 最多移除此队列中给定数量的可用元素,并将它们添加到给定的集合中。
forEach​(Consumer 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 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 c) | 将指定 collection 中的所有元素添加到此队列中。
clear() | 从此队列中删除所有元素。
element() | 检索,但不删除,此队列的头。
remove() | 检索并删除此队列的头。

### java.util.AbstractCollection 类中声明的方法

方法 | 描述
—|—
containsAll​(Collection c)

如果此 collection 包含指定 collection 中的所有元素,则返回 true。
toString() 返回此集合的字符串表示形式。

java.util.concurrent.BlockingQueue 接口中声明的方法

方法 描述
poll​(long timeout, TimeUnit unit) 检索并移除此队列的头部,等待指定的等待时间(如果需要)以使元素可用。
take() 检索并移除此队列的头部,如果需要,一直等待直到元素可用。

java.util.Collection 接口中声明的方法

方法 描述
addAll​(Collection c) | 将指定 collection 中的所有元素添加到此 collection 中(可选操作)。
clear() | 删除此 collection 中的所有元素(可选操作)。
containsAll​(Collection c)
如果此 collection 包含指定 collection 中的所有元素,则返回 true。
equals​(Object o) 将指定的对象与此 collection 进行比较以实现相等性。
hashCode() 返回此 collection 的哈希码值。
parallelStream() 返回与此 collection 作为其源进行可能并行处理的 Stream。
stream() 返回以此 collection 作为其源的顺序 Stream。
toArray​(IntFunction<T[]> generator) 使用提供的生成器函数分配返回数组,返回包含此 collection 中所有元素的数组。

java.util.Queue 接口中声明的方法

方法 描述
element() 检索,但不删除,此队列的头。
peek() 检索但不删除此队列的头部,如果此队列为空则返回 null。
poll() 检索并删除此队列的头部,如果此队列为空则返回 null。
remove() 检索并删除此队列的头部。

java.util.concurrent.TransferQueue 接口中声明的方法

方法 描述
getWaitingConsumerCount() 返回所有消费者在调用BlockingQueue.take()或带超时参数的poll()时正在等待接收元素的估计数量。
hasWaitingConsumer() 如果至少有一个消费者正在等待通过调用BlockingQueue.take()或带超时参数的poll()来接收一个元素,则返回true。

参考网址: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/LinkedTransferQueue.html

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程