"BlockQueue<E>" 's common methods :
The blocking queue methods fall into three categories that differ by the action they perform when the queue is full or empty. If you use the queue as a thread management tool, use the "put" and "take" methods. The "add", "remove", and "element" operations throw an exception when you try to add to a full queue or get the head of an empty queue. Of cause, in a multithreaded program, the queue might become full or empty at any time, so you will instead want to use the "offer", "poll", and "peek" methods. These methods simply return with a failure indicator instead of throwing an exception if they cannot carry out their tasks.
java.util.concurrent.BlockingQueue<E> :
void put(E element)
// add the element, blocking if necessary.
E take()
// removes and returns the head element, blocking if necessary
boolean offer(E element, long time, TimeUnit unit)
// adds the given element and returns "true" if successful, blocking
// if necessary until the element has been added or the time has elapsed.
E poll(long time, TimeUnit unit)
//removes and returns the head element, blocking if necessary until an element is available or the time has elapsed.
//Returns "null" upon failure.
The "java.util.concurrent" package supplies several variations of blocking queues. By default, the "LinkedBlockingQueue" has no upper bound on its capacity, but a maximum capacity can be optional specified. The "LinkedBlockingQueue" is a "double-ended" version. The "ArrayBlockingQueue" is constructed with a given capacity and an optional parameter to require fairness. If fairness is specified, then the longes-waiting threads are given preferential treatment. As always, fairness exacts a significant performance penalty, and you should only use it if your problem specifically requires it.
The "PriorityBlockingQueue" is a priority queue, not a first-in/first-out queue. Elements are removed in order of their priority. The queue has unbounded capacity, but retrival will block if the queue is empty.
A "DelayQueue" contains objects that implement the "Delayed" interface:
interface Delayed extends Comparable<Delayed> {
long getDelay(TimeUnit unit);
}
The "getDelay" method returns the remaining delay of the object. A negative value indicates that the delay has elapsed. Element can only be removed from a "DelayQueue" if their delay has elapsed. You also need to implement the "compareTo" method. The "DelayQueue" uses the method to sort the entries.
Java SE 7 adds a "TransferQueue" interface that allows a producer thread to wait until a consumer is ready to take an item. When a producer calls
q.transer(item);
the call blocks until another thread removes it. The "LinkedTransferQueue" class implements this interface.
java.util.concurrent.ArrayBlockingQueue<E>:
ArrayBlockingQueue(int capacity)
ArrayBlockingQueue(int capacity, boolean fair)
// constructs a blocking queue with the given capacity and fairness setting.
// The queue is implemented as a circular array.
java.util.concurrent.LinkedBlockingQueue<E>
java.util.concurrent.LinkedBlockingDequeue<E>
LinkedBlockingQueue();
LinkedBlockingDequeue();
// construct an unbounded blocking queue or dequeue, implemented as a linked list.
LinkedBlockingQueue(int capacity)
LinkedBlockingDequeue(int capacity)
// constructs a bounded blocking queue or dequeue with the given capacity,
// implemented as a linked list.
java.util.concurrent.DelayQueue<E extends Delayed>
DelayQueue()
// constructs an unbounded queue of "Delayed" elements.
// Only elements whose delay has expired can be removed from the queue.
java.util.concurrent.Delayed
long getDelay(TimeUnit unit)
// gets the delay for the object, measured in the given time unit.
java.util.concurrent.PriorityBlockingQueue<E>
PriorityBlockingQueue()
PriorityBlockingQueue(int initialCapacity)
PriorityBlockingQueue(int initialCapacity, Comparator<? super E> comparator)
//constructs an unbounded blocking priority queue implemented as a heap
// Parameters "initialCapacity" The initial capacity. Default is 11.
// "comparator" The comparator used to compare elements.
// If not specified, the elements must implement the "Comparable" interface
The following example shows how to use a blocking queue to control a set of threads.
package ConcurrentTest;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* Created by lenovo on 2018/6/18.
*/
public class BlockingQueueTest {
private static final int FILE_QUEUE_SIZE = 10;
private static final int SEARCH_THREADS = 1000;
private static final File DUMMY = new File("");
private static BlockingQueue<File> queue = new ArrayBlockingQueue<>(FILE_QUEUE_SIZE);
public static void enumerate(File directory) throws InterruptedException {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
enumerate(file);
} else {
queue.put(file);
}
}
}
}
public static void search(File file, String key) {
try (Scanner in = new Scanner(file, "UTF-8")) {
int lineNumber = 0;
while (in.hasNextLine()) {
String line = in.nextLine();
lineNumber++;
if(line.contains(key)) {
System.out.printf("%s:%d:%s\n", file.getPath(), lineNumber, line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("Please Enter a directory: ");
try (Scanner in = new Scanner(System.in)) {
String directory = in.nextLine();
System.out.println("Enter a key: ");
String key = in.nextLine();
Runnable enumerator = () -> {
try {
enumerate(new File(directory));
queue.put(DUMMY);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
};
new Thread(enumerator).start();
for (int i = 0; i < SEARCH_THREADS; i++) {
Runnable searchor = () -> {
try {
boolean isDone = false;
while (!isDone) {
File file = queue.take();
if (file == DUMMY) { // using this trick to terminate the application is greate.
queue.put(file);
isDone = true;
} else {
search(file, key);
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
};
new Thread(searchor).start();
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}