Talking about the application of synchronized keyword in Android

processes and threads

In the study of operating systems, I have mentioned two concepts of "process" and "thread". I will not discuss their origin here. First of all, I want to talk about some similarities and differences between processes and threads.

In fact, from the underlying nature of the computer, there is no difference between a process and a thread in terms of memory space. They are all loaded, allocated, and then do your own thing.

In the era before "threads" were born, computers used "processes" as the smallest scheduling unit, and programs were all in the form of single threads; Efficiency can no longer meet market demand, so "thread" was born. It replaces "process" as the smallest scheduling unit, and "process" becomes the smallest memory allocation unit

In the past, when we opened an application, the process had to process a series of operations such as program initialization, interface rendering, etc., which were handed over to the process to operate in a serial manner, even making network requests and downloading multiple files. time, also download one by one. But when there are threads, the process is upgraded from the underlying worker to the contractor - it starts to assign its original work to each thread to do, and the process only needs to be responsible for scheduling and receiving callbacks

An application corresponds to a process, which can contain multiple threads, and these threads can be assigned to each core of the CPU and operate.

Why use threads?

The advantage of using multi-threading is that the current development trend of CPU has changed from increasing the core frequency to increasing the number of cores. Under the multi-core CPU architecture, multi-threading can more efficiently utilize the computing resources of the CPU, and also improve the efficiency of program operation.

Applications in Android Development

Without leaving this line, how do we apply multi-threaded development in Android development?

First imagine the use case...

The author summarizes it as: when manipulating data

Yes, when we read and write data, we often encounter concurrent reads and writes of the same piece of data within a very short period of time. For example, when using the sqlite database to read and write local data, obtain background data, send data to the background for writing, etc...

I have encountered similar problems in the projects I have developed. Because the magnitude of this project is not heavy, the data we need to cache locally is n JSONStrings. For this reason, the development team did not use sqlite but sharedpreferences to store local data, the format is as follows:

key value
root [address1, address2, address3……]
address1 JSONString1
address2 JSONString2
…… ……

Each time a piece of cached data is sent to the backend, the backend replies to confirm receipt and deletes the corresponding key-address, and then rewrites the root

The problem arises when the root is rewritten, the parallel pool has a limited capacity of 5, and 5 threads are created to send the data of address1, address2, address3, address4, and address5, but the operation for the root is "first read the root -> delete the corresponding address --> writeback", which may cause the following problems:

Thread 1 operation Thread 2 operation
read in root
send data read in root
send data
get reply confirmation get reply confirmation
remove address1 from root remove address2 from root
write back
write back

Found something wrong?

When thread 2 ends, address1 still exists in the root written back!

synchronized

Putting the solutions to the above problems aside, I will first talk about the synchronized keyword.

For java, the most commonly used synchronization mechanism is the synchronized keyword, which is a rough language-based lock that can act on objects, functions, and classes. Each object has only one lock, and whoever can get the lock has access rights. When synchronized acts on a function, the object is actually locked, and the locked object is the object of the class where the function is located. When synchronized acts on a class, it is the class of the lock, not a specific object.

According to different writing methods, synchronized can lock a specific object or a method in it. When multiple threads need to call this object, the waiting operation will be scheduled according to the FIFO method; synchronized can also act on A class with a wider scope, all instance objects of this class will be restricted by the same lock

We can lock a method of an object:

public synchronized void f(){}

You can also lock a block of code on an object:

synchronized (this){}

You can also lock static methods of a class:

public synchronized static void staticF(){}

You can also lock a block of code for a class:

synchronized (SynchronizedClass.class){}

The first two kinds of locks are objects, and the last two kinds of locks are classes. For a class, its role is to prevent multiple threads from accessing the code block with the synchronized lock at the same time, and the effect of synchronized on the object is to prevent other threads from accessing the synchronized code block or function in the same object.

Synchronized-based solution

After so much foreshadowing, in fact, the solution is very simple, just encapsulate the sharedpreferences operation into a class and then lock it.

(Lu out Jia laughs)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324770646&siteId=291194637