The above example unconditionally blocks other threads from accessing a method asynchronously. The application of implicit pipe in Java objects is very powerful, but you can achieve a more subtle realm through interprocess communication. This is especially simple in Java.
As discussed earlier, multithreading replaces the event loop program by dividing the task into discrete and logical units. The thread has a second advantage: it is far from polling. Polling is usually implemented by a loop that repeats the condition of the monitoring. Once the conditions are set, appropriate action is necessary. This wastes CPU time. For example, consider the classic sequence problem when one thread is generating data and another program is consuming it. To make the problem more interesting, assume that the data generator must wait for the consumer to complete the work to produce new data. In polling systems, consumers waste a lot of CPU cycles while waiting for producers to generate data. Once the producer finishes the job, it will start polling, wasting more CPU time waiting for the end of the consumer's work, so go on. Obviously, this is not a popular situation.
To avoid polling, Java contains an inter-process communication mechanism implemented through the wait (), notify (), and Notifyall () methods. These methods are implemented in the object with the final method, so all classes contain them. These three methods can only be called in the Synchronized method. Although these methods are highly advanced in concept from the perspective of computer science, it is very simple to use them in practice:
- Wait () tells the called thread to discard the pipe to sleep until another thread enters the same pipe and calls notify ().
- Notify () Restores the first thread in the same object that calls wait ().
- Notifyall () Restores all the threads in the same object that call Wait (). The thread with the highest priority runs first.
These methods are declared in object, as follows:
final void Wait () throws Interruptedexception
Final void Notify ()
final void Notifyall ()
Another form of wait () existence allows you to define the waiting time.
The following example program incorrectly implements a boards/consumer problem. It consists of four classes: Q, which manages to obtain synchronized sequences, Producer, generates queued thread objects, Consumer, consumes sequences of thread objects, and PCs, creates a single q,producer, and a small class of Consumer.
1 //An incorrect implementation of a producer and consumer.2 classQ {3 intN;4 synchronized intget () {5System.out.println ("Got:" +n);6 returnN;7 }8 synchronized voidPutintN) {9 This. N =N;TenSystem.out.println ("Put:" +n); One } A } - classProducerImplementsRunnable { - q q; the Producer (q q) { - This. Q =Q; - NewThread ( This, "Producer"). Start (); - } + Public voidrun () { - inti = 0; + while(true) { AQ.put (i++); at } - } - } - classConsumerImplementsRunnable { - q q; - Consumer (q q) { in This. Q =Q; - NewThread ( This, "Consumer"). Start (); to } + Public voidrun () { - while(true) { the q.get (); * } $ }Panax Notoginseng } - classPC { the Public Static voidMain (String args[]) { +Q q =NewQ (); A NewProducer (q); the NewConsumer (q); +System.out.println ("Press Control-c to stop.")); - } $}
Although the put () and get () methods in the Q class are synchronous, nothing prevents producers from exceeding consumers, and nothing prevents consumers from consuming the same sequence two times. In this way, you get the following error output (the output will change with the processor speed and load Task):
Put:1
Got:1
Got:1
Got:1
Got:1
Got:1
Put:2
Put:3
Put:4
Put:5
Put:6
Put:7
Got:7
After producers generate 1, consumers get the same 15 times in turn. Producers continue to generate 2 to 7, and consumers do not have access to them.
The program written correctly in Java is marked in two directions with wait () and notify (), as shown below:
1 //a correct implementation of a producer and consumer.2 classQ {3 intN;4 BooleanValueSet =false;5 synchronized intget () {6 if(!ValueSet)7 Try {8 wait ();9}Catch(interruptedexception e) {TenSYSTEM.OUT.PRINTLN ("Interruptedexception caught"); One } ASystem.out.println ("Got:" +n); -ValueSet =false; - notify (); the returnN; - } - synchronized voidPutintN) { - if(ValueSet) + Try { - wait (); +}Catch(interruptedexception e) { ASYSTEM.OUT.PRINTLN ("Interruptedexception caught"); at } - This. N =N; -ValueSet =true; -System.out.println ("Put:" +n); - notify (); - } in } - classProducerImplementsRunnable { to q q; + Producer (q q) { - This. Q =Q; the NewThread ( This, "Producer"). Start (); * } $ Public voidrun () {Panax Notoginseng inti = 0; - while(true) { theQ.put (i++); + } A } the } + classConsumerImplementsRunnable { - q q; $ Consumer (q q) { $ This. Q =Q; - NewThread ( This, "Consumer"). Start (); - } the Public voidrun () { - while(true) {Wuyi q.get (); the } - } Wu } - classpcfixed { About Public Static voidMain (String args[]) { $Q q =NewQ (); - NewProducer (q); - NewConsumer (q); -System.out.println ("Press Control-c to stop.")); A } +}
Internal get (), wait () is called. This causes the execution to hang until the producer informs the data that it is ready. At this point, the internal get () is resumed execution. After getting the data, get () calls notify (). This tells producer that more data can be entered into the sequence. Within put (), wait () suspends execution until consumer takes the items in the sequence. When execution continues, the next data item is put into sequence, notify () is called, which informs consumer that it should move the data.
The following is the output of the program, which clearly shows the synchronization behavior:
Put:1
Got:1
Put:2
Got:2
Put:3
Got:3
Put:4
Got:4
Put:5
Got:5
Series Articles:
Java know how much (top)
Java know how much (interface) interface
Java knows how much (40) the difference between an interface and an abstract class
Java know how much (41) generic explanation
Java know how much (42) the range of generic wildcard characters and type parameters
Java know how much (43) Exception Handling Basics
Java know how much (44) exception type
Java know how much (45) uncaught exceptions
How much Java knows (the) use of try and catch
Java know how much (47) use of multiple catch statements
Java knows how much (in) the nesting of Try statements
Java know how much (a) throw: Exception throws
Java know how many () Java throws clauses
Java knows how many (or) finally
Java know how much (52) built-in exceptions
Java know how much (53) Use Java to create your own exception subclasses
Java know how much (54) assertion detailed
Java know how many (55) threads
Java know how much (56) threading ModelJava know how much (57) main threadJava know how much (58) thread Runnable interface and thread class explanationJava know how much (59) Create multithreadingJava know how much (isAlive) and join () useJava know how much (61) thread PriorityJava know how much (62) thread synchronization
Java know how much (63) inter-thread communication