1# Comparison Between the Actor and Memory Sharing Models 2 3In the memory sharing model, multiple threads execute complex tasks simultaneously. These threads depend on the same memory and have the permission to access the memory. Before accessing the memory, a thread must preempt and lock the memory. In this case, other threads have to wait for the thread to release the memory. 4 5In the actor model, each thread is an independent actor, which has its own memory. Actors trigger the behavior of each other through message transfer. They cannot directly access the memory space of each other. 6 7Different from the memory sharing model, the actor model provides independent memory space for each thread. As such, it avoids memory preemption and resulting function and performance problems. 8 9In the actor model, concurrent tasks and task results are transmitted through the inter-thread communication. 10 11This topic describes the differences between the two models when solving the producer-consumer problem. 12 13## Memory Sharing Model 14The following figure shows how the producer-consumer problem is resolved in the memory sharing model. 15 16 17 18To prevent dirty reads and writes caused by simultaneous access, only one producer or consumer can access a shared memory container at a time. This means that producers and consumers need to compete for the lock of the container. After a role obtains the lock, other roles have to wait. 19 20``` 21// Below is pseudocode and is provided to help you better understand the differences between the memory sharing model and the actor model. 22BufferQueue { 23 Queue queue 24 Mutex mutex 25 add(value) { 26 // Attempt to acquire the lock. 27 if (mutex.lock()) { 28 queue.push(value) 29 mutex.unlock() 30 } 31 } 32 33 take() { 34 // Attempt to acquire the lock. 35 if (mutex.lock()) { 36 if (queue.empty()) { 37 return null 38 } 39 let res = queue.pop(value) 40 mutex.unlock() 41 return res 42 } 43 } 44} 45 46// Construct a globally shared memory segment. 47let g_bufferQueue = new BufferQueue() 48 49Producer { 50 run() { 51 let value = random() 52 // Initiate cross-thread access to the bufferQueue object. 53 g_bufferQueue.add(value) 54 } 55} 56 57Consumer { 58 run() { 59 // Initiate cross-thread access to the bufferQueue object. 60 let res = g_bufferQueue.take() 61 if (res != null) { 62 // Add consumption logic. 63 } 64 } 65} 66 67Main() { 68 let consumer = new Consumer() 69 let producer = new Producer() 70 // Execute the production task in multiple threads. 71 for 0 in 10 : 72 let thread = new Thread() 73 thread.run(producer.run()) 74 consumer.run() 75} 76``` 77 78## Actor Model 79The following figure shows how the producer-consumer problem is resolved by using **TaskPool** in the actor model. 80 81 82 83In the actor model, different roles do not share memory. Both the producer thread and UI thread have their own exclusive memory. After producing the result, the producer sends the result to the UI thread through serialization. After consuming the result, the UI thread sends a new production task to the producer thread. 84 85```ts 86import taskpool from '@ohos.taskpool'; 87// Cross-thread concurrent tasks 88@Concurrent 89async function produce(): Promise<number>{ 90 // Add production logic. 91 console.log("producing..."); 92 return Math.random(); 93} 94 95class Consumer { 96 public consume(value : number) { 97 // Add consumption logic. 98 console.log("consuming value: " + value); 99 } 100} 101 102@Entry 103@Component 104struct Index { 105 @State message: string = 'Hello World' 106 107 build() { 108 Row() { 109 Column() { 110 Text(this.message) 111 .fontSize(50) 112 .fontWeight(FontWeight.Bold) 113 Button() { 114 Text("start") 115 }.onClick(() => { 116 let produceTask: taskpool.Task = new taskpool.Task(produce); 117 let consumer: Consumer = new Consumer(); 118 for (let index: number = 0; index < 10; index++) { 119 // Execute the asynchronous concurrent production task. 120 taskpool.execute(produceTask).then((res : number) => { 121 consumer.consume(res); 122 }).catch((e : Error) => { 123 console.error(e.message); 124 }) 125 } 126 }) 127 .width('20%') 128 .height('20%') 129 } 130 .width('100%') 131 } 132 .height('100%') 133 } 134} 135``` 136