Blocking queues: Thread safety
Sort elements by FIFO (first-in first out). The head of the queue is the element with the longest time in the queue. The tail of the queue is the element with the shortest time in the queue. The new element is inserted at the end of the queue, and the queue retrieval operation obtains the element at the head of the queue. The throughput of a linked queue is typically higher than an array-based queue, but in most concurrent applications it has a low predictable performance.
Attention:
1, must use the Take () method to achieve the blocking result when obtains
2, using the poll () method will produce non-blocking effect
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;
Import Java.util.concurrent.LinkedBlockingDeque;
Import Java.util.concurrent.LinkedBlockingQueue;
Import Java.util.concurrent.TimeUnit; public class Blockingdeque {//blocking queue, FIFO private static linkedblockingqueue<integer> Concurrentlinkedqueue =
New Linkedblockingqueue<integer> ();
public static void Main (string[] args) {Executorservice executorservice = Executors.newfixedthreadpool (2);
Executorservice.submit (New Producer ("Producer1"));
Executorservice.submit (New Producer ("Producer2"));
Executorservice.submit (New Producer ("Producer3"));
Executorservice.submit (New Consumer ("Consumer1"));
Executorservice.submit (New Consumer ("Consumer2"));
Executorservice.submit (New Consumer ("Consumer3"));
Static Class Producer implements Runnable {private String name; Public Producer (String name) {THis.name = name; public void Run () {for (int i = 1; i < ++i) {System.out.println (name+) Production:
"+ i);
Concurrentlinkedqueue.add (i);
try {concurrentlinkedqueue.put (i); Thread.Sleep (200);
Simulate slow production, resulting in blocking effects} catch (Interruptedexception E1) {//TODO auto-generated catch block
E1.printstacktrace ();
"}}} static class Consumer implements Runnable {private String name;
Public Consumer (String name) {this.name = name;
public void Run () {for (int i = 1; i < ++i) {try {
You must use the Take () method to block System.out.println (name+ "consumption:" + Concurrentlinkedqueue.take ()) at the time of acquisition; Using the poll () method produces a non-blocking effect//system.out.println (name+ "consumption:" + Concurrentlinkedqueue.poll ());
There is also a time-out usage, when the queue is empty, the specified blocking time is returned and will not always block//But there is a question as to why the blocking queue is called if it is not blocked.
System.out.println (name+ "Consumer" + concurrentlinkedqueue.poll (timeunit.milliseconds)); catch (Exception e) {//TODO auto-generated catch block e.printst
Acktrace (); }
}
}
}
}
Non-blocking queues
Based on link nodes, unbounded, thread-safe. This queue sorts the elements according to the FIFO (first-in first out) principle. The head of the queue is the longest element in the queue. The tail of the queue is the element with the shortest time in the queue. The new element is inserted into the tail of the queue, and the queue retrieval operation obtains the element from the queue header. Concurrentlinkedqueue is an appropriate choice when many threads share access to a public collection. This queue does not allow null elements.
Example
Import Java.util.concurrent.ConcurrentLinkedQueue;
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;
Import Java.util.concurrent.LinkedBlockingDeque;
Import Java.util.concurrent.TimeUnit; public class Noblockqueue {private static concurrentlinkedqueue<integer> Concurrentlinkedqueue = new Concu
Rrentlinkedqueue<integer> ();
public static void Main (string[] args) {Executorservice executorservice = Executors.newfixedthreadpool (2);
Executorservice.submit (New Producer ("Producer1"));
Executorservice.submit (New Producer ("Producer2"));
Executorservice.submit (New Producer ("Producer3"));
Executorservice.submit (New Consumer ("Consumer1"));
Executorservice.submit (New Consumer ("Consumer2"));
Executorservice.submit (New Consumer ("Consumer3"));
Static Class Producer implements Runnable {private String name; Public ProDucer (String name) {this.name = name; public void Run () {for (int i = 1; i < ++i) {System.out.println (NA
Me+ "Start producer" + i);
Concurrentlinkedqueue.add (i);
try {thread.sleep (20); catch (Interruptedexception e) {//TODO auto-generated catch block E.printstack
Trace ();
}//system.out.println (name+ "End producer" + i);
}} Static Class Consumer implements Runnable {private String name;
Public Consumer (String name) {this.name = name;
public void Run () {for (int i = 1; i < ++i) {try {
System.out.println (name+ "Consumer" + concurrentlinkedqueue.poll ());
catch (Exception e) { TODO auto-generated Catch block E.printstacktrace ();
}//System.out.println ();
System.out.println (name+ "End Consumer" + i); }
}
}
}
In concurrent programming, blocking queues are generally recommended, so that the implementation can avoid unexpected errors in the program as much as possible. The most classic scenario for blocking queues is to read and parse the socket client data, and the thread that reads the data keeps the data in the queue, and then parses the thread from the queue to parse the data continuously. There are other similar scenarios where blocking queues can be used as long as the producer-consumer model is met.
Using non-blocking queues, although results can be returned immediately (consumption results), it is necessary to encode the solution to return to empty cases (and consumption retries, etc.).
In addition, they are thread-safe, regardless of thread synchronization issues.