Thread coordination
In Java multithreading, you can use the synchronized modifier to modify the instance resources shared between threads to synchronize between threads. In addition, the coordination between threads must be considered in the multi-threaded design. A typical design pattern for coordination is the Producer-Consumer) pattern.
Producer-Consumer) Mode
In this mode, there are two types of threads: Producer and Consumer. The Producer thread is used to generate Data sharing Data resources), and the Consumer thread is used to consume Data between Producer and Consumer, there is a coordination between Data generation and consumption, that is, when there is no Data, the Consumer thread needs to wait for the Producer thread to generate new Data, and when there are too many Data, the Producer thread needs to wait for the Consumer thread to consume too much Data. In the Producer-Consumer mode, Channel pipelines are introduced to coordinate Data among various threads. The following figure shows the UML class diagram of the Producer-Consumer mode.
650) this. width = 650; "style =" width: 553px; height: 290px "border =" 0 "alt =" "src =" http://www.bkjia.com/uploads/allimg/131228/1225103957-0.jpg "width =" 583 "height =" 317 "/>
In, both the Producer Thread class and the Consumer Thread class contain references to Channel class objects, while Channel class objects encapsulate Data classes, the synchronous methods of production and consumption Data are also implemented, namely, produce and consume. In the produce and consume methods, Data coordination is further achieved by using the wait and notifyAll methods.
Wait, policy, and policyallIn Java, wait, policy, and policyall are Object-class methods used to pause and wake up threads that call Object methods. Wait is used to suspend a thread and put it into the wait set thread of the object to wait for the set). The Y and yyall methods are used to wake up the thread in the wait set and keep it running. Notify and policyall are different. When there are multiple threads in the wait set, notify will only wake up one thread at random, while notifyAll will wake up all threads from them for competition, obtain the synchronization lock and continue execution.
A simple example of using wait, policy, and policyall.
650) this. width = 650; "border =" 0 "alt =" "src =" http://www.bkjia.com/uploads/allimg/131228/1225104000-1.jpg "width =" 614 "height =" 382 "/>
Implementation example of the Producer-Consumer Mode
Producer and Consumer thread classes
- Package com. wt. pc;
-
- Public class Producer extends Thread {
-
- // Reference the Channel object
- Channel channel = null;
- // Consumer Constructor
- Public Producer (String producerName, Channel channel)
- {
- Super (producerName );
- This. channel = channel;
- }
- // The Producer thread attempts to generate new data every MS
- Public void run ()
- {
- Try {
- While (true)
- {
- Channel. produce (Integer. toString (Channel. dataId ++ ));
- Thread. sleep (500 );
- }
- } Catch (Exception e ){}
- }
- }
- Package com. wt. pc;
-
- Public class Consumer extends Thread {
-
- // Reference the Channel object
- Channel channel = null;
- // Consumer Constructor
- Public Consumer (String consumerName, Channel channel)
- {
- Super (consumerName );
- This. channel = channel;
- }
- // The Consumer thread tries to consume data every MS
- Public void run ()
- {
- Try {
- While (true)
- {
- Channel. consume ();
- Thread. sleep (500 );
- }
- } Catch (Exception e ){}
- }
-
- }
Channel and Data class
- Package com. wt. pc;
-
- Public class Channel {
- // Static variable used to generate the data name
- Static int dataId = 0;
- // Data storage array
- Data dataList [];
- // The sequence number of the currently unconsumed data Header
- Int head;
- // The next end number of the currently unconsumed data
- Int tail;
- // Number of data not consumed currently
- Int count;
- // Channel Constructor
- // The array capacity is 3, and other values are initialized to 0.
- Public Channel ()
- {
- DataList = new Data [3];
- Head = 0;
- Tail = 0;
- Count = 0;
- }
-
- // The produce method for generating data
- Public synchronized void produce (String dataName) throws Exception {
- // When the array capacity is full, that is, when the new data cannot be regenerated, the current thread enters the wait set
- While (count> = 3)
- {
- Wait ();
- }
- // Generate new data
- System. out. println (Thread. currentThread (). getName () + "is producing" + dataName );
- DataList [tail] = new Data ();
- DataList [tail]. setDataName (dataName );
- Tail = (tail + 1) % 3;
- Count ++;
- Thread. sleep (400 );
- // Wake up the thread in the wait set
- Policyall ();
- }
- // Consume method, used to consume data
- Public synchronized void consume () throws Exception {
- // When the array capacity is empty, that is, when data cannot be consumed, the current thread enters the wait set
- While (count <= 0)
- {
- Wait ();
- }
- // Consume data
- System. out. println (Thread. currentThread (). getName () + "is consuming" + dataList [head]. getDataName ());
- Head = (head + 1) % 3;
- Count --;
- Thread. sleep (300 );
- // Wake up the thread in the wait set
- Policyall ();
- }
- }
- package com.wt.pc;
- public class Data {
- String dataName;
-
- public String getDataName() {
- return dataName;
- }
-
- public void setDataName(String dataName) {
- this.dataName = dataName;
- }
- }
Main Function
- public static void main(String args[])
- {
- Channel channel = new Channel();
- new Producer("p1",channel).start();
- new Producer("p2",channel).start();
- new Producer("p3",channel).start();
- new Consumer("c1",channel).start();
- new Consumer("c2",channel).start();
- new Consumer("c3",channel).start();
-
- }
Execution result
P2 is producing 0 C2 is consuming 0 P3 is producing 2 P1 is producing 1 C3 is consuming 2 C1 is consuming 1 P1 is producing 5 P3 is producing 4 C2 is consuming 5 P2 is producing 3 P3 is producing 7 C1 is consuming 4 C3 is consuming 3 P3 is producing 9 P1 is producing 6 C2 is consuming 7 P2 is producing 8 C3 is consuming 9 C1 is consuming 6 P2 is producing 12 P3 is producing 10 C2 is consuming 8 ...... |
From the execution results, we can see that the number of executions of the generated Data thread p and the number of executions of the consumption Data thread c always meet the following requirements: p> = c and p <= c + 3 ensure that the Data array has Data but does not exceed the array capacity during consumption, so as to effectively implement Data coordination between the Producer and Consumer thread classes.
Summary
In Java multithreading design, synchronization and coordination between threads must be fully considered. Different design modes can be used for different application scenarios, existing design modes include Single Threaded Execution, Immutable, Guarded Suspension, Balking, Producer-Consumer, Read-Write Lock, Thread-Per-Message, and Worker Thread, for details, refer to the "Java multithreading design mode" tutorial on the Internet.
This article is from the "Learning document" blog, please be sure to keep this source http://zephiruswt.blog.51cto.com/5193151/937337