Thread synchronization:
The synchronized keyword: prevents multiple threads from executing at the same time
The volatile keyword: the shared variable is modified to indicate that when the thread modifies the value of the variable, the new value is immediately visible to other threads
Conditions of use: 1. The write operation to the variable does not depend on the current value
2. The variable is not included in the invariants of other variables
When a statement contains multiple operations, it is not an atomic operation (only a simple read assignment is)
Blocking queue:
Commonly used in producer-consumer scenarios, producer: thread that adds elements to the queue; consumer: thread that takes elements out of the queue
For common blocking scenarios, blocking queues are supported:
1. When there is no data in the queue, all threads on the consumer end will be blocked automatically until there is data put into the queue
2. When the queue data is not full, all data on the producer side will be blocked automatically until there is an empty position in the queue
Blocking queue core method:
put into a:
offer(object)--Add the object to the blocking queue, if it can be added, return true, otherwise return false (do not block the thread of the current method)
offer(E o, long timeout, TimeUnit unit)--Set the waiting time, if you can't add it to the queue within the specified time, you will regret and fail
put(object) -- add the object to the queue, if there is no space, the thread calling this method will be blocked until there is space to continue
Obtain:
poll(long timeout, TimeUnit unit)-- take out the first element in the queue, return immediately if it can be fetched, otherwise return failure if the timeout has not yet elapsed
take()--take out the first element of the queue, if it is empty, enter the waiting state until it is not empty
drainTo()--Get all available data objects from the queue at one time, without the need to lock or release locks in batches multiple times
Java's 7 blocking queues:
ArrayBlockingQueue: A bounded blocking queue composed of an array structure that does not guarantee thread fairness: that is, the producer that blocks first can insert elements into the queue first, and the consumer that blocks first can obtain elements from the queue first
LinkedArrayBlockingQueue: A bounded blocking queue composed of a linked list structure. When the producer puts data into the queue, the queue will get it from the producer. Only when the queue buffer reaches the maximum value will the producer queue be blocked until the consumer gets out of the queue. Only after consuming a data producer thread can it resume work. Advantages: can efficiently process concurrent data
PriorityBlockingQueue: An unbounded blocking queue that supports priority sorting. By default, it is sorted in ascending order. You can customize the sorting rules
DelayQueue: An unbounded blocking queue that supports delayed acquisition of elements. You can specify the expiration time of elements, and only when they expire can they be removed from the queue.
SynchronizedQueue: A blocking queue that does not store elements, and there are no elements inside the queue
LinkedTransferQueue: an unbounded blocking queue composed of linked lists
LinkedBlockingQueue: A two-way blocking queue composed of linked lists, with more methods such as addFirst, addLast, offerFirst, offerLast, etc.
Thread Pool:
corePoolSize: number of core threads
maxPoolSize: The maximum number of threads, if exceeded, new threads will be created
keepAliveTime: The idle timeout of non-core threads. If this event is exceeded, non-core threads will be recycled. If allowCoreThreadTimeOut is set to true, keepAliveTime will also be applied to core threads
TimeUnit: The time unit of keepAliveTime, which can be DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS.
workQueue: If the current number of threads is greater than corePoolSize, add this task to the task queue
threadFactory: thread factory, generally no need to set parameters
RejectedExecutionHandler: Saturation strategy, when the task queue and thread pool are full, new tasks cannot be processed by default and an exception is thrown
The maximum number of threads allowed to be created by the thread pool is 128, and the maximum time for non-core threads to idle for new tasks is 1s
The processing flow of the thread pool:
1. The thread first judges whether the number of threads reaches the number of core threads, and if not, creates a core thread to process the task.
2. Then the thread pool judges whether the task queue is full, if not add the task to the task queue.
3. The task queue is full, and the thread pool judges whether the number of threads has reached the maximum number of threads. If not, create a non-core thread to process the task, otherwise execute the saturation strategy
Types of thread pools:
1. FixedThreadPool: only core threads, and the number is fixed
2. CachedThreadPool: corePoolSize=0, maxPoolSize=Integer.MAX_VALUE, need to create a thread pool of threads, no core threads, more suitable for a large number of tasks that need to be processed immediately and consume less time
3. SingleThreadExecutor: corePoolSize=maxPoolSize=1, which can ensure that all tasks are executed sequentially in one thread
4.ScheduledThreadPool: thread pool for timing and periodic tasks, corePoolSize is a fixed value, maxPoolSize parameter is invalid
The principle of AsyncTask:
Background: When multiple tasks update the UI, the code will be bloated. AsyncTask makes asynchronous tasks very simple
Features: It is an abstract generic class
public abstract class AsyncTask<Params, Progress, Result>{
...
}
Params: parameter type; Progress: background task execution progress type; Result: return result type
4 core methods:
1. onPreExecute(): Executed in the main thread, generally the preparation work before task execution
2. doInBackground(Params): Generally used to perform time-consuming operations, you can call publishProgress() to update the progress bar during the process
3. onProgressUpdate(Progress): Executed in the main thread, when calling publishProgress, the progress will be updated on the UI
4. onPostExecute(Result): The finishing work after the background task is executed, such as updating UI and data, etc.