Java concurrent Programming (ix) Inter-threading collaboration (bottom)

Source: Internet
Author: User

In the previous article we talked about using wait () and notify () to collaborate between threads, which is straightforward and flexible, but before using the lock of the object, the number of notify () calls that are less than the number of waiting threads can cause threads to wait. The advantage of indirect collaboration is that it is simpler to use and less error-prone, as we talk about the way in which multithreading works indirectly, blocking queues and piping traffic.

blocking queues

A blocking queue provides the ability to throw an object at any point in the queue, and if the queue is full, the current thread is blocked, and at any moment an object can be fetched from the queue, and the current thread is blocked if the queue is empty. The blocking queue is thread-safe and does not need to be locked when it is used. In addition, the internal synchronization is implemented using a display lock, and thread blocking is implemented using condition. The interface to the blocking queue is Blockingqueue, which has two implementation classes:

1. Arrayblockingqueue: A queue implemented using an array at the bottom, with a fixed length, must provide the maximum length of the queue when calling its construction method.

2. Linkedblockingqueue: The bottom of the queue using the linked list, in theory, there is no maximum length, so that time does not provide queue length, but in fact, the length of this queue can not exceed integer.max_value.

These two classes use the time is not very different, we take linkedblockingqueue as an example, rewrite the "students go to the cafeteria to play rice" example, the code is as follows:

classStudentImplementsRunnable {PrivateObject wan =NewObject ();  Public voidrun () {Try{System.out.println ("Student: Take a bowl.");            BlockingQueueTest.wanQueue.put (WAN); System.out.println ("Student: Aunt Help Sheng Fan"); Wan=BlockingQueueTest.wanWithFanQueue.take (); System.out.println ("Student: Dinner"); } Catch(Interruptedexception e) {} }}classCafeteriaworkerImplementsRunnable { Public voidrun () {Try{Object Wan=BlockingQueueTest.wanQueue.take (); System.out.println ("Aunt: Sheng Fan for students");        BlockingQueueTest.wanWithFanQueue.put (WAN); } Catch(Interruptedexception e) {} }} Public classBlockingqueuetest { Public StaticBlockingqueue Wanqueue =NewLinkedblockingqueue ();  Public StaticBlockingqueue Wanwithfanqueue =NewLinkedblockingqueue ();  Public Static voidMain (string[] args) {Executorservice exec=Executors.newcachedthreadpool (); Exec.execute (NewStudent ()); Exec.execute (NewCafeteriaworker ());    Exec.shutdown (); }}

The output results are as follows:

Student: Take a bowl

Student: Aunt Help Sheng Fan

Aunt: Sheng Fan for students

Student: Dinner

In this example we define two queues, one for the empty bowl and the other for the bowl of the meal. The student thread takes the empty bowl into the Wanqueue queue after taking the bowl, and then tries to take the good job out of the wanwithfanqueue queue; "Aunty thread" tries to remove the empty bowl from the Wanqueue queue and then puts the good job in the Wanwithfanqueue queue. The last time we used the Wait () method, we had to ask "Auntie Thread" to start first, otherwise it would cause the "Auntie thread" to miss the student's signal, while using the blocking queue we would no longer require two threads to boot up the sequence, using a blocking queue to circumvent the risk of missed signals. Some students may wonder why they use two queues, because if the same queue is used, the classmate thread throws the bowl into the queue, the "Aunt thread" may be taken back by the "classmate thread" before it can be taken out.

Pipeline communication

Pipelines can also be used to make interactions between threads, like pipelines and blocking queues, which are blocked if a thread attempts to read data when there is no data in the pipeline.

We can use PipedWriter and Pipedreader to implement the reading and writing of the pipe data. Unlike a blocking queue, a different thread in a blocking queue is an object that operates on one queue, and when a pipe is used, different threads can use different objects as long as they are registered as a single pipe.

We use pipeline communication to simulate one thread to another thread, and the code is as follows:

classSenderImplementsRunnable {PrivatePipedWriter writer; Sender (PipedWriter writer) { This. writer =writer; }     Public voidrun () {String str1=NewString ("I Love you\n"); String str2=NewString ("Do Your Love me\n"); Try{writer.write (Str1.tochararray ());        Writer.write (Str2.tochararray ()); } Catch(IOException e) {} }}classReceiverImplementsRunnable {PrivatePipedreader Reader;  PublicReceiver (Pipedreader reader) { This. Reader =reader; }     Public voidrun () {Try {             while(true) {                Charc = (Char) Reader.read ();            System.out.print (c); }        } Catch(IOException e) {} }} Public classpipecommunication { Public Static voidMain (string[] args)throwsException {Pipedreader reader=NewPipedreader (); PipedWriter writer=NewPipedWriter (reader); Executorservice exec=Executors.newcachedthreadpool (); Exec.execute (NewSender (writer)); Exec.execute (NewReceiver (reader)); Thread.Sleep (1000);    Exec.shutdownnow (); }}

After running the output results are as follows, one second after the program exits:

I Love You

Do Your Love Me

We define a Pipedreader object in the main method and pass the object as a parameter of the constructor of the PipedWriter to the PipedWriter object, so that we can bind the two input and output streams and pass two stream objects to two thread objects respectively. In the receiver of information we use a dead loop to keep it from being read in from the pipeline, and from the output we can see that the read () method is blocked when there is no data in the pipeline because the output does not cycle through other characters. In addition, the main thread sleep a second after the call of the Shutdownnow () method, this method to all the running thread to send the interrupt signal, the program runs a second after the exit, we can see interrupt signal interrupted receiver blocking state, It concludes that the pipe class can be interrupted by an interrupt signal when it is blocked.

Summarize

This article describes the use of blocking queues and pipelines for inter-threading collaboration, which is more advanced, easier and less error-prone than using wait () collaboration, and that blocking queues and pipelines are thread-safe, so you don't need to use locks when using them. When you need to implement inter-threading collaboration, you can choose between tradeoffs based on actual needs.

Public number: Today said yards. Follow my public number to see the serial article. If you do not understand the problem, directly in the public message can be.

Java concurrent Programming (ix) Inter-threading collaboration (bottom)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.