Inter thread communication

await 2021-09-15 09:58:30

The above example unconditionally blocks other threads from accessing a method asynchronously .Java The application of implicit pipeline in object is very powerful , But you can reach a more subtle level through interprocess communication . This is in Java It's very simple in the middle .

As discussed earlier , Multithreading replaces event loop programs by dividing tasks into discrete and logical units . Threads have a second advantage : It's away from polling . Polling is usually implemented by a cycle of repeated monitoring conditions . Once the conditions are established , Take appropriate action . It's a waste CPU Time . for instance , Consider the classical sequence problem , When one thread is generating data and another program is consuming it . To make the problem more interesting , Suppose that the data generator must wait for the consumer to complete the work before generating new data . In the polling system , Consumers waste a lot waiting for producers to produce data CPU cycle . Once the producer has finished the work , It will start polling , Waste more CPU Time to wait for the end of the consumer's work , Go on like this . Obviously , This situation is not welcome .

To avoid polling ,Java It includes passing through wait( ),notify( ) and notifyAll( ) Method to implement an inter process communication mechanism . These methods are used in objects final Method , So all classes contain them . These three methods are only in synchronized Method can be called . Although these methods are highly advanced in terms of the direction of computer science , It is very simple to use in practice : wait( ) Tell the called thread to give up the process and go to sleep until other threads enter the same process and call notify( ). notify( ) Restore the first call in the same object wait( ) The thread of . notifyAll( ) Restore all calls in the same object wait( ) The thread of . The thread with the highest priority runs first .

These methods are in Object It is stated in the statement that , As shown below :

final void wait( ) throws InterruptedException
final void notify( )
final void notifyAll( )

wait( ) Another form of existence allows you to define the waiting time .

The following example program incorrectly implements a simple producer / Consumer issues . It consists of four classes :Q, Try to get a synchronized sequence ;Producer, Generate queued Thread objects ;Consumer, The thread object of the consumption sequence ; as well as PC, Create a single Q,Producer, and Consumer A small class of . // An incorrect implementation of a producer and consumer. class Q {

int n;
synchronized int get() {
System.out.println("Got: " + n);
return n;
}
synchronized void put(int n) {
this.n = n;
System.out.println("Put: " + n);
}

} class Producer implements Runnable {

Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}

} class Consumer implements Runnable {

Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}

} class PC {

public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}

} Even though Q Class put( ) and get( ) Method is synchronous , Nothing prevents producers from surpassing consumers , Nothing prevents consumers from spending the same sequence twice . such , You get the following error output ( The output will vary depending on the processor speed and the tasks loaded ): 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 Producers generate 1 after , Consumers get the same... In turn 1 Five times . The producer is continuing to generate 2 To 7, Consumers have no access to them .

use Java The correct way to write this program is to use wait( ) and notify( ) To mark both directions , As shown below : // A correct implementation of a producer and consumer. class Q {

int n;
boolean valueSet = false;
synchronized int get() {
if(!valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
if(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}

} class Consumer implements Runnable {

Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}

} class PCFixed {

public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}

} Inside get( ), wait( ) Called . This suspends execution until Producer Inform that the data is ready . At this time , Inside get( ) Be resumed execution . After data acquisition ,get( ) call notify( ). This tells Producer You can enter more data into the sequence . stay put( ) Inside ,wait( ) Suspend execution until Consumer Removed items from the sequence . When executed, continue , The next data item is put into the sequence ,notify( ) Called , This notice Consumer It should remove the data .

Here is the output of the program , It 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 The above example unconditionally blocks other threads from accessing a method asynchronously .Java The application of implicit pipeline in object is very powerful , But you can reach a more subtle level through interprocess communication . This is in Java It's very simple in the middle .

As discussed earlier , Multithreading replaces event loop programs by dividing tasks into discrete and logical units . Threads have a second advantage : It's away from polling . Polling is usually implemented by a cycle of repeated monitoring conditions . Once the conditions are established , Take appropriate action . It's a waste CPU Time . for instance , Consider the classical sequence problem , When one thread is generating data and another program is consuming it . To make the problem more interesting , Suppose that the data generator must wait for the consumer to complete the work before generating new data . In the polling system , Consumers waste a lot waiting for producers to produce data CPU cycle . Once the producer has finished the work , It will start polling , Waste more CPU Time to wait for the end of the consumer's work , Go on like this . Obviously , This situation is not welcome .

To avoid polling ,Java It includes passing through wait( ),notify( ) and notifyAll( ) Method to implement an inter process communication mechanism . These methods are used in objects final Method , So all classes contain them . These three methods are only in synchronized Method can be called . Although these methods are highly advanced in terms of the direction of computer science , It is very simple to use in practice : wait( ) Tell the called thread to give up the process and go to sleep until other threads enter the same process and call notify( ). notify( ) Restore the first call in the same object wait( ) The thread of . notifyAll( ) Restore all calls in the same object wait( ) The thread of . The thread with the highest priority runs first .

These methods are in Object It is stated in the statement that , As shown below :

final void wait( ) throws InterruptedException
final void notify( )
final void notifyAll( )

wait( ) Another form of existence allows you to define the waiting time .

The following example program incorrectly implements a simple producer / Consumer issues . It consists of four classes :Q, Try to get a synchronized sequence ;Producer, Generate queued Thread objects ;Consumer, The thread object of the consumption sequence ; as well as PC, Create a single Q,Producer, and Consumer A small class of . // An incorrect implementation of a producer and consumer. class Q {

int n;
synchronized int get() {
System.out.println("Got: " + n);
return n;
}
synchronized void put(int n) {
this.n = n;
System.out.println("Put: " + n);
}

} class Producer implements Runnable {

Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}

} class Consumer implements Runnable {

Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}

} class PC {

public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}

} Even though Q Class put( ) and get( ) Method is synchronous , Nothing prevents producers from surpassing consumers , Nothing prevents consumers from spending the same sequence twice . such , You get the following error output ( The output will vary depending on the processor speed and the tasks loaded ): 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 Producers generate 1 after , Consumers get the same... In turn 1 Five times . The producer is continuing to generate 2 To 7, Consumers have no access to them .

use Java The correct way to write this program is to use wait( ) and notify( ) To mark both directions , As shown below : // A correct implementation of a producer and consumer. class Q {

int n;
boolean valueSet = false;
synchronized int get() {
if(!valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
if(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}

} class Consumer implements Runnable {

Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}

} class PCFixed {

public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}

} Inside get( ), wait( ) Called . This suspends execution until Producer Inform that the data is ready . At this time , Inside get( ) Be resumed execution . After data acquisition ,get( ) call notify( ). This tells Producer You can enter more data into the sequence . stay put( ) Inside ,wait( ) Suspend execution until Consumer Removed items from the sequence . When executed, continue , The next data item is put into the sequence ,notify( ) Called , This notice Consumer It should remove the data .

Here is the output of the program , It 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

This article altogether 1684 Number of words , Average reading time ≈ 5 minute

Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .

Please bring the original link to reprint ,thank
Similar articles

2021-09-15