Thread collaboration and communication instances of Java multi-line Cheng

Source: Internet
Author: User
Tags emit

The difficulty of multithreading is mainly multi-threaded communication collaboration This piece, the previous note two mentioned in the common synchronization method, here is the case study, summed up a few 3 examples today:

1, bank deposit and withdrawal multi-threaded implementation, using lock lock and condition condition. Attach: Use a monitor for inter-thread communication

2, the producer consumer realizes, uses the LinkedList self-write buffer.

3, multi-thread block queue learning, using blocking queue to quickly implement the producer consumer model. Attaching: Closing a thread with a Boolean variable

Of the three thread synchronization methods, our example here uses lock lock to implement variable synchronization because it is more flexible and intuitive.

The synchronization of variables is implemented, and we have to make a "call" between multiple threads, that is, after a thread has completed a condition, tell the other threads that I have completed this condition and you can move on. Here is the synchronization method defined by the conditional interface condition provided by Java:

It is convenient that the Java lock lock inside provides the Newconditon () method can, the method returns: a lock lock is bound to the condition instance, a bit abstract, actually think of it as a can send information on the lock can be, look at the following code, should be able to understand.

1. Multi-threaded implementation of bank deposits and withdrawals.

We simulate the deposit and withdrawal of ATM machines, create an account (), which contains the synchronization method:

Deposit Method: Deposit ()

Withdrawal method: Withdraw ()

And a common method of querying the Balance getbalance ().

We create two task threads, call two synchronous methods, and perform the simulation operation to see the code:

Import Java.util.concurrent.executorservice;import Java.util.concurrent.executors;import Java.util.concurrent.locks.condition;import Java.util.concurrent.locks.lock;import Java.util.concurrent.locks.reentrantlock;public class Threadcooperation {private static account ' account ' = new account ()   ; public static void Main (string[] args) {//create thread pool Executorservice executor = Executors.newfixedthreadpool (2); Executor.execute (New Deposittask ()); Executor.execute (new Withdrawtask ()); Save public static class Deposittask implements runnable{@Overridepublic void Run () {try {while (true) {Account.deposit ( int) (Math.random () *1000) +1); Thread.Sleep (1000);}} catch (Interruptedexception e) {e.printstacktrace ();}}} public static class Withdrawtask implements runnable{@Overridepublic void Run () {Try{while (true) {Account.withdraw (int ) (Math.random () *1000) +1); Thread.Sleep (500);}} catch (Interruptedexception e) {e.printstacktrace ();}}} public static class account{//A lock is an instance of a lock interface it defines the method of locking and releasing the lock Reentrantlock is to create a phaseThe specific implementation of the lock of the mutually exclusive lock is private static lock lock = new Reentrantlock ();//creates a condition with a notification function, provided that the lock interface is implemented with the private static Condition newdeposit = lock.newcondition ();p rivate int balance = 0;public int getbalance () {return balance;} public void Withdraw (int. amount) {lock.lock (); try {while (Balance < amount) {System.out.println ("\t\t not enough, waiting to save money"); Newdeposit.await ();} Balance-= amount; System.out.println ("\t\t Take Out" +amount+ "block money \ t remaining" +getbalance ());} catch (Interruptedexception e) {e.printstacktrace ();} Finally{lock.unlock ();}} public void deposit (int amount) {lock.lock (); try{balance+=amount;   System.out.println ("Deposit" +amount+ "block Money"); Newdeposit.signalall (); The message wakes all threads}finally{lock.unlock ();}}}

Run

Analysis:

1, the program needs to note: To create a condition, with the notification function of the lock, the premise is to implement the lock interface.

2, while (balance < amount) can not use if to judge, with if will make the thread unsafe, use if would not be cyclic verification, while the while will, we often see while (true), but not often see if (true).

3, after calling the await method, remember to use Signalall () or signal () to wake the thread, otherwise the thread waits forever.

Finally, to analyze the structure of this class, there are 3 classes, two static task classes implement the Runnable interface, is a thread class, and the other class is a common task class, contains the thread class used by the method. Our main class instantiates an account class in front of the main method for the thread class to invoke the synchronization method inside the class.

This kind of construction is a common way to construct multithreading. It is not difficult to find the producer consumer model behind the handwriting is also such a sub-structure. This is equivalent to a multithreaded template. It is also the most important thing for us to learn this example.

Communicating between threads using a monitor

Also, interface lock and condition appear after java5, and before that, thread communication is implemented through the built-in monitor.

A monitor is an object that is mutually exclusive and capable of synchronizing, and any object can become a monitor. A monitor is a synchronized keyword to its own locking (locking unlocking is the most basic idea of resolving thread synchronization), when the Wait () method is used, the thread pauses and waits for the condition to occur, and the notification is sent through the Notify () and Notifyall () methods. The general template is this:

It is not difficult to see that await (), signal (), signally () are the evolutionary patterns of Wait (), notify (), and Notifyall (), so it is not recommended to use a monitor.

2, the producer consumer realizes, uses the LinkedList self-write buffer

This model has been very classic, learning the operating system when also learned, remember that Linux also use PV operation to achieve it, but this thing is interdisciplinary.

Consider the users, producers and consumers of buffer buffers, who can identify whether the buffers are full, and both can emit only one signal:

Producer: It can emit a notempty () signal, that is, a non-empty signal of the buffer, when it sees the buffer full, it calls await waiting.

Consumer: It can emit a notfull () signal, which is a signal that the buffer is not full, and when it sees the buffer empty, it also calls await waiting.

Look at the code:

Import Java.util.concurrent.executorservice;import Java.util.concurrent.executors;import Java.util.concurrent.locks.condition;import Java.util.concurrent.locks.lock;import java.util.concurrent.locks.reentrantlock;//producer Consumer public class Consumerproducer {private static Buffer buffer= new Buffer ();p ublic static void Main (string[] args) {Executorservice executor = Executors.newfixedthreadpool (2); Executor.execute (New Producertask ()); Executor.execute (new Consumertask ()); Executor.shutdown ();} public static class Producertask implements runnable{@Overridepublic void Run () {int I=1;try {while (true) { System.out.println ("producer writes data" +i); Buffer.write (i++); Thread.Sleep ((int) (Math.random () *80));} }catch (interruptedexception e) {e.printstacktrace ();}}} public static class Consumertask implements Runnable{public void Run () {try {while (true) {System.out.println ("\t\t consume read-out data "+buffer.read ()); Thread.Sleep ((int) (Math.random () *100));}} catch (Interruptedexception e) {e.printstacktrace ();}}} public static Class Buffer{private static final int capactiy = 4; Buffer capacity Private java.util.linkedlist<integer> queue = new java.util.linkedlist<integer> ();p rivate static Lock lock = new Reentrantlock ();p rivate static Condition notempty = Lock.newcondition ();p rivate static Condition Notfull = Lock.newcondition ();p ublic void write (int value) {lock.lock (); Try{while (Queue.size () ==capactiy) { System.out.println ("Buffer full"); Notfull.await ();}  Queue.offer (value); Notempty.signalall (); Notifies all buffers that are not empty}catch (Interruptedexception ex) {ex.printstacktrace ();} Finally{lock.unlock ();}} @SuppressWarnings ("finally") public int read () {int value = 0;lock.lock (); Try{while (Queue.isempty ()) { SYSTEM.OUT.PRINTLN ("\t\t buffer is empty, wait for buffer non-empty case"); notempty.await ();} Value = Queue.remove (); notfull.signal ();} catch (Interruptedexception ex) {ex.printstacktrace ();} Finally{lock.unlock (); return value;}}}

Run

The program works fine, but a little longer reading time, this is the case

The program inside the capacity is 4, but here can be deposited up to 5 data, and more reasonable should be the initial buffer is empty, followed by this small bug, the original call offer () function should be placed in the detection statement, if you want to start to call Consumertask, You can change the order of the two in the main method.

3. Rapid implementation of producer consumer model with blocking queue

The power of Java is that it has a rich library of classes, and we learn Java in a way that is learning these kinds of libraries.

A blocking queue is a queue that, when attempting to add elements to a full queue or remove elements from an empty queue, causes the thread to block automatically, and when the queue is full, the queue continues to store elements for use by the awakened thread. This should be said to be a kind of queue designed for the consumer producer model, it realizes the queue interface, the main method is put () and take () method.

Java supports three specific blocking queues Arrayblockingqueue, Linkedblockingqueue, Priorityblockingqueue. are in the Java.util.concurrent package.

Briefly describe the above three blocking queues:

Arrayblockingqueue: The block is implemented in an array, according to FIFO, that is, first-out principle to sort the data, and the use of the group is a bit similar, it needs to specify a capacity in advance, but even if the queue exceeds this capacity, it will not be error drops.

Linkeddblockingqueue: With the linked list implementation, the default queue size is Integer.max_value, but also according to the first-out method to sort the data, performance may be more than arrayblockingqueue, pending research.

Priorityblockingqueue: A blocking queue implemented with a priority queue that sorts the elements by size or creates an unrestricted queue, and the Put method never blocks.

OK, look at the code:

Import Java.util.concurrent.arrayblockingqueue;import Java.util.concurrent.executorservice;import Java.util.concurrent.executors;public class Consumerproducerusingblockqueue {private static arrayblockingqueue< integer> buffer = new arrayblockingqueue<integer> (2);p ublic static void Main (string[] args) {Executorservice Executor = Executors.newfixedthreadpool (2); Executor.execute (new Consumer ()); Executor.execute (new Producer ()); try {     Thread.Sleep (+); Executor.shutdownnow (); Violent close, will error, not recommended} catch (Interruptedexception e) {//TODO auto-generated catch Blocke.printstacktrace ();}} public static class Consumer implements runnable{@Overridepublic void Run () {Try{int I=1;while (true) {System.out.println ("creator writes:" +i); Buffer.put (i++); Thread.Sleep ((int) (Math.random ()) *1000);}} catch (Interruptedexception ex) {ex.printstacktrace ();}}} public static class Producer implements runnable{@Overridepublic void Run () {Try{while (true) {System.out.println ("\t\ T consumers take out "+buffer.take ()"); Thread.Sleep ((int) (MatH.random ()) *10000);}} catch (Interruptedexception ex) {ex.printstacktrace ();}}}}

Run:

No big problem, that is, when the thread is turned off too violent, will error, the thread inside each function seems worth studying, before want to pause through interrupt, but failed, directly using the thread pool executor Shoutdownnow method. Later, I used another method to close the thread, see the following code

Use Linkedblockingqueue to implement consumer producers and use Boolean variables to control thread shutdown
Import Java.util.concurrent.executorservice;import Java.util.concurrent.executors;import Java.util.concurrent.linkedblockingqueue;public class A_control_stop {private static linkedblockingqueue<string > buffer = new linkedblockingqueue<string> ();p ublic static void Main (string[] args) {Executorservice executor = E Xecutors.newfixedthreadpool (2); Executor.execute (new Consumer ()); Executor.execute (new Producer ()); Executor.shutdown (); while (!executor.isterminated ()) {}system.out.println ("All Threads end normally");}  public static class Consumer implements Runnable{private volatile Boolean exit = false; @Overridepublic void Run () {Try{int i=0; string[] Str ={"as", "D", "SD", "EW", "SDFG", "ESFR"};while (!exit) {System.out.println ("creator writes:" +str[i]); Buffer.put (str [i++]); Thread.Sleep ((int) (Math.random ()) *10); if (5==i) {exit=true;}}} catch (Interruptedexception ex) {ex.printstacktrace ();}}}  public static class Producer implements Runnable{private volatile Boolean exit = false; @Overridepublic void Run () {Try{int I=0;whIle (!exit) {System.out.println ("\t\t Consumer Take Out" +buffer.take ()); i++; Thread.Sleep ((int) (Math.random ()) *10); if (5==i) {exit=true;}}} catch (Interruptedexception ex) {ex.printstacktrace ();}}}}

About blocking the queue, I think this article is very good, recommend everyone to see and talk about the blocking queues in concurrent----Java

Used for a few days, multithreading is to learn a little fur, note: These days the article is mainly referred to the "Java programming language design into the 8th edition", the Foreigner wrote the book speak really good, but now Java has been updated to JAVA8. On some other sites to see their articles, no description of what is reproduced, is estimated to be directly "collected" past.

This article is from the blog Garden Orchid Secluded, please indicate the source of the reprint.

Thread collaboration and communication instances of Java multi-line Cheng

Related Article

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.