Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
introduce
Dart is a single-threaded model without the concept of multi-threading in Android, but that doesn’t mean asynism doesn’t exist. Asynchronous operations certainly exist in applications. Dart provides something similar to the concept of threads — ISOLATE. So there’s no concurrency, some people call it ISOLATE, threads like processes. The Android and Dart virtual machine models are as follows:
Isolate create
In DART, a primary ISOLATE is created by default after executing the main method at startup. How do you create a sub-ISOLATE to perform asynchronous tasks? The isolate provides its own static method spawn to create an ISOLATE. This method requires two mandatory parameters:
- EntryPoint: Specifies the initial function to call in the generated ISOLATE.
- Message: Parameter to receive in the entryPoint function, usually used to pass sendPort for ISOLATE communication.
void main(){
Isolate.spawn(entryPoint, "message");
}
void entryPoint(String message){
print(message);
}
Copy the code
Verify memory isolation
Once the sub-isolates are created, can we verify that the different isolates are memory isolated? The following describes how to declare a global NUM, assign num to the main isolate, print num values in the main isolate and sub-ISOLATE respectively. The console logs show that no num value can be obtained in the sub-isolate.
int num;
void main(){
num = 1;
Isolate.spawn(entryPoint, "message");
print("main num $num");
}
void entryPoint(String message){
print("entryPoint num $num");
}
Copy the code
Isolate communication
Like Android, where we use handlers to communicate with threads, let’s see how the ISOLATE in DART sends and receives data.
ReceivePort receivePort = ReceivePort(); receivePort.listen((message) { print(message); }); ReceivePort. SendPort. Send (" this is communication message "); receivePort.sendPort.send(1);Copy the code
Create a receiver ReceivePort, send messages using its sender, sendPort, and listen to receive the sent messages through ReceivePort’s Listen method. It is important to note that the data sent in SEND is of unlimited type.
The “message” parameter in spawn is usually sendport that is passed to the main ISOLATE to communicate between the different isolates. That is, I give you my sender and prepare a receiver to receive the message sent by the sender. When you need to send a message through the sender to send a message to me:
void main(){ ReceivePort receivePort = ReceivePort(); Isolate.spawn(entryPoint, receivePort.sendPort); receivePort.listen((message) { print(message); }); } void entryPoint(SendPort SendPort){// Simulate time-consuming operation future.delayed (Duration(seconds: 2),(){sendport.send (" Messages sent to you inside the subisolate "); }); }Copy the code
As shown in the figure, the Main ISOLATE received a message sent from the child ISOLATE 2 seconds later.
Two-way communication
It says that we can communicate with the main ISOLATE using the sender of the sub-isolate. Then we can communicate with the main ISOLATE using the sender of the sub-isolate using the main Isolate. The send method does not limit the type of data to be sent. Therefore, after receiving main ISOLATE data, you can send the sender of the sub-ISOLATE first, and then send other communication data:
void main(){ ReceivePort receivePort = ReceivePort(); Isolate.spawn(entryPoint, receivePort.sendPort); Receiveport. listen((message) {if(message is SendPort){print(" Main received the sender of subisolate "); Future.delayed(Duration(seconds: 1),(){message.send(" Main sends messages to subisolate "); }); }else{ print(message); }}); } void entryPoint(SendPort sendPort){ ReceivePort receivePort = ReceivePort(); Receiveport. listen((message) {print(" main received message: $message"); }); sendPort.send(receivePort.sendPort); Future.delayed(Duration(seconds: 2),(){sendport.send (" Messages sent to main from subisolate "); }); }Copy the code
As shown below, main first receives a sender from the sub-isolate and then sends a message to the sub-isolate using this sender, enabling two-way communication between both ends.
Receiveport.close () is always called when the receiver is no longer in use.
Status method of the ISOLATE
Suspended:
isolate.pause(isolate.pauseCapability);
Copy the code
Recovery:
isolate.resume(isolate.pauseCapability);
Copy the code
The end:
isolate.kill(priority: Isolate.immediate);
Copy the code