One, Producer-consumer mode
Producer: A producer means a thread that generates data.
Consumer: The consumer means that the thread that uses the data
When producers and consumers run on different threads, the difference in processing speed between them can cause problems. For example, consumers want to get data, but the data hasn't been generated yet.
Or the producer wants to deliver the data, and the consumer's state is not able to receive it.
The Producer-consumer model adds a bridge role between producer consumers. The bridge role is used to eliminate differences in the processing speed between threads.
In this model, producers and consumers have multiple, when consumers and producers have only one, called pipe mode
Two, examples
/*** Table class is used to represent the table where the cake is placed. * The container that holds the cake is an array. So the cake is placed in order, and the cake is ordered. */ Public classTable {Private Finalstring[] buffer;//the container that actually holds the cake Private intTail//the position of the next put Private intHead//where to take next time Private intCount//the number of cakes in buffer PublicTable (intcount) { This. Buffer =NewString[count]; This. Tail = 0; This. Head = 0; This. Count = 0; } //Place Cake Public synchronized voidPut (String cake)throwsinterruptedexception{System.out.println (Thread.CurrentThread (). GetName ()+ "put" +cake); while(Count >=buffer.length) {Wait (); } Buffer[tail]=cake; Tail= (tail+1)%buffer.length; Count++; Notifyall (); } //fetch the cake . Public synchronizedString Take ()throwsinterruptedexception{ while(Count <= 0) {wait (); } String Cake=Buffer[head]; Head= (head+1)%buffer.length; Count--; Notifyall (); System.out.println (Thread.CurrentThread (). GetName ()+ "takes" +cake); returncake; }}
Public classMakerthreadextendsThread {Private Finalrandom random; Private Finaltable table; Private Static intid = 0;//the serial number of the cake PublicMakerthread (String name, table table,Longseed) { Super(name); This. Random =NewRandom (SEED); This. Table =table; } @Override Public voidrun () {Try { while(true) {Thread.Sleep (Random.nextint (1000)); String Cake= "[Cake NO." +nextid () + "by" +getname () + "]"; Table.put (cake); } }Catch(Interruptedexception e) {}}Private Static synchronized intNextID () {returnid++; }}
Public classEaterthreadextendsThread {Private Finalrandom random; Private Finaltable table; PublicEaterthread (String name, table table,Longseed) { Super(name); This. Random =NewRandom (SEED); This. Table =table; } @Override Public voidrun () {Try { while(true) {String cake=Table.take (); Thread.Sleep (Random.nextint (1000)); } }Catch(Interruptedexception e) {} }}
Public classTest { Public Static voidMain (string[] args) {table Table=NewTable (3); NewMakerthread ("MakerThread-1", table,31415). Start (); NewMakerthread ("MakerThread-2", table,92653). Start (); NewMakerthread ("MakerThread-3", table,58979). Start (); NewEaterthread ("EaterThread-1", table,32384). Start (); NewEaterthread ("EaterThread-2", table,62643). Start (); NewEaterthread ("EaterThread-3", table,38327). Start (); }}
Three, interruptedexception abnormal
1. The method of adding interruptedexception
The wait method for the Java.lang.Object class
The sleep method of the Java.lang.Thread class
Join method for the Java.lang.Thread class
2. The method of adding throws interruptedexception may take time, but it can be canceled
The time spent is reflected in:
Execution of the wait method requires waiting for the Notify/notifyall method to wake up and takes time
Execution of the Sleep method pauses execution, which also takes time
Executes the join method, waits for the specified thread to terminate, takes time
Can be canceled as reflected in:
If the Alice thread executes Thread.Sleep (100000), we can use Alice.interrupt () in another thread, and when the interrupt is executed, the thread that is asleep terminates the paused state, and the Alice thread throws
Interruptedexception exception. This way, the control of the thread Alice is transferred to the catch statement block that captures the exception.
The 3.interrupt method only changes the interrupt state
After calling interrupt above, the thread throws the interruptedexception exception, just because the Alice thread called the thread Break method (Wait,sleep,join).
When a thread performs normal logical processing, even if another thread calls Alice.interrupt (); It does not throw an exception, but continues execution. Only if the thread continues to perform calls to methods such as Sleep,wait,join,
The interruptedexception exception is thrown
4, when other threads execute Alice.interrupt (), there is no need to acquire a lock on the Alice thread instance, and any thread can invoke the interrupt method of another thread whenever
The difference between 5.notify and interrupt:
??????????
Four, isinterrupted method: Check interrupt status
Isinterrupted is an instance method of the thread class that checks the interrupt state of the specified thread.
If the specified thread is in a broken state: Returns True,
Not in interrupt state: returns false
Five, thread.interrupted: Check and clear interrupt status
This method is a static method of the thread class that checks and clears the interrupt state of the current thread (the action object is the thread itself)
Returns true if the current thread is in a broken state. And the current thread's interrupt status is clear.
Returns False if the current thread is not in a broken state.
Six, the queue in the Java.util.concurrent package
1.BlockingQueue Interface: Blocking queue
This interface represents a queue that has been blocked (wait) by the front-thread in the appropriate state. Implementation class:
1). Arrayblockingqueue class: Array-based Blockingqueue
Blockingqueue with a limited number of elements
2). Linkedblockingqueue class: Linked List-based Blockingqueue
The number of elements is not the maximum limit, as long as there is memory, you can always put the data
3). Priorityblockingqueue class: Blockingqueue with Priority
The priority of the data is specified based on the natural ordering of the comparable interface, or in the order in which the comparator interface of the constructor is determined.
4). Synchronousqueue class: Direct transfer of Blockingqueue
This class is used to perform direct delivery by the producer role to the consumer role. If the producer role is put first, the thread of the producer role will block until the consumer role take.
Instead, it blocks.
2.ConcurrentLinkedQueue class: Thread-safe queue with no maximum limit on number of elements
In concurrentlinkedqueue, internal data structures are separate and threads do not affect each other, so there is no need for mutex processing
3. Replace the table class in the above instance program with Arrayblockingqueue
Code:
/*** Use the blocking queue to complete the function of table*/ Public classBlockqueuetableextendsArrayblockingqueue<string>{ PublicBlockqueuetable (intcapacity) { Super(capacity); } Public voidPut (String cake)throwsinterruptedexception {System.out.println (Thread.CurrentThread (). GetName ()+ "puts" +cake); Super. put (cake); } PublicString Take ()throwsinterruptedexception {String cake=Super. Take (); System.out.println (Thread.CurrentThread (). GetName ()+ "takes" +cake); returncake; }}
Multi-threaded series six: Producer-consumer mode