Multithreading and java Multithreading
I. Implementation of multithreading in iOS
Ii. NSThread1. create and start a thread
An NSThread object represents a thread.
Create and start a thread
1-(void) viewDidLoad {2 [super viewDidLoad]; 3 // create and enable a sub-thread 4 NSThread * thread = [[NSThread alloc] initWithTarget: self selector: @ selector (run :) object: @ "parameter"]; 5 // when the thread starts, it will execute self's run Method 6 [thread start] In the thread; 7} 8/** 9 * enable the sub-thread 10*11 * @ param parameter 12 */13-(void) run :( NSString *) param14 {15 NSLog (@ "currentThread: % @ -- run -- % @", [NSThread currentThread], param); 16} 17 18 print result: 19 <NSThread: 0x7fd5b2f207f0> {number = 2, name = (null)} -- run -- Parameter
Main thread usage
1 + (NSThread *) mainThread; // obtain the master thread 2-(BOOL) isMainThread; // whether the master thread 3 + (BOOL) isMainThread; // whether the master thread
Other usage
Obtain the current thread NSThread * current = [NSThread currentThread]; Thread Scheduling Priority + (double) threadPriority; + (BOOL) setThreadPriority :( double) p;-(double) threadPriority; -(BOOL) setThreadPriority :( double) p; the value range of the scheduling priority is 0.0 ~ 1.0. The default value is 0.5. The larger the value, the higher the priority, the thread name-(void) setName :( NSString *) n;-(NSString *) name;
Other thread creation methods
After a thread is created, the thread [NSThread detachNewThreadSelector: @ selector (run) toTarget: self withObject: nil] is automatically started. The thread [self created mselectorinbackground: @ selector (run) withObject: nil];
Advantages and disadvantages of the above two thread creation methods
- Advantage: simple and quick
- Disadvantage: the thread cannot be set in more detail.
2. Control thread status
Start thread-(void) start; // enter the ready state-> running state. When the thread task is completed, it automatically enters the dead state blocking (pause) thread + (void) sleepUntilDate :( NSDate *) date; + (void) sleepForTimeInterval :( NSTimeInterval) ti; // force stop thread + (void) exit to enter the blocking status; // enter the dead state
Note: Once the thread stops (dead), the task cannot be started again.
3. mutex lock
Mutex lock format: @ synchronized (Lock Object) {// code to be locked}
Note: Only one lock is used to lock one piece of code. Multiple locks are invalid.
Advantages and disadvantages of mutex lock
- Advantage: it can effectively prevent data security problems caused by multi-thread resource grabbing.
- Disadvantage: it consumes a lot of CPU resources.
Prerequisite for mutex lock: multiple threads snatch the same resource
Related terminology: Thread Synchronization
Thread Synchronization means that multiple threads execute tasks in sequence.
The mutex lock uses the thread synchronization technology.
4. Atomic and non-atomic attributes
OC has two options: nonatomic and atomic when defining attributes.
- Atomic: atomic attribute, locking the setter method (the default value is atomic)
- Nonatomic: Non-atomic attribute. It does not lock the setter method.
Atomic Locking Principle
1 @property (assign, atomic) int age;2 3 - (void)setAge:(int)age4 {5 @synchronized(self) {6 _age = age;7 }8 }
Nonatomic and atomic comparison
- Atomic: thread security, which consumes a lot of resources
- Nonatomic: Non-thread-safe, suitable for mobile devices with small memory
5. Inter-thread Communication
Inter-thread Communication
One thread transmits data to another thread
After a specific task is executed in one thread, go to another thread to continue the task.
Common Methods for inter-thread communication:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
Iii. Introduction to GCD1.
The full name is Grand Central Dispatch, which is pure C language and provides many powerful functions.
GCD advantages
- GCD is a solution developed by Apple for multi-core parallel computing
- GCD will automatically use more CPU cores (such as dual-core and quad-core)
- GCD automatically manages the thread lifecycle (creating threads, scheduling tasks, and destroying threads)
- The programmer only needs to tell GCD what task to execute and does not need to write any thread Management Code.
2. Tasks and queues
There are two core concepts in GCD
- Task: What operations are performed
- Queue: used to store tasks
Add a task to the queue:
- GCD automatically extracts tasks from the queue and puts them in the corresponding thread for execution.
- Task retrieval follows the FIFO principle of the queue: first-in-first-out, and then-out
3. Execute the task
There are two functions in GCD used to execute tasks.
- Execute the task in synchronous mode. queue: queue block: Task
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
- Execute tasks in asynchronous mode
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
Differences between synchronous and asynchronous
- Synchronization: executed in the current thread
- Asynchronous: executed in another thread
4. Queue type
GCD queues can be divided into two types:
- Concurrent Dispatch Queue: enables Concurrent (Concurrent) Execution of multiple tasks (automatically enabling multiple threads to execute tasks simultaneously). The Concurrent function is only asynchronous (dispatch_async) valid only under the Function
- Serial Dispatch Queue: Let the task be executed one by one (after a task is executed, the next task is executed)
5. Concurrent queue
By default, GCD provides a global concurrent queue for the entire application.
Use the dispatch_get_global_queue function to obtain the global concurrent queue.
Dispatch_queue_t priority (queue priority, // queue priority unsigned long flags); // this parameter is temporarily useless. Use 0 to dispatch_queue_t queue = dispatch_get_global_queue (queue, 0 ); // obtain the global concurrency queue
Priority of global concurrent queues
# Define DISPATCH_QUEUE_PRIORITY_HIGH 2 // high # define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // default (medium) # define limit (-2) // low # define limit INT16_MIN // background
6. Serial queue
There are two methods to obtain serial numbers in GCD.
Use the dispatch_queue_create function to create a serial queue
Struct (const char * label, // queue name dispatch_queue_attr_t attr); // queue attribute. Generally, use NULL to dispatch_queue_t queue = dispatch_queue_create ("queue", NULL ); // create dispatch_release (queue); // The manually created queue needs to be released without the ARC
Use the main queue column (queue associated with the main thread)
The main queue is a special serial queue that comes with GCD.
All tasks in the main queue are executed in the main thread.
Use dispatch_get_main_queue () to obtain the main queue Column
dispatch_queue_t queue = dispatch_get_main_queue();
7. Execution Effects of Various queues
8. Example of Inter-thread Communication
Return from sub-thread to main thread
1 dispatch_async (2 dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {3 // executes time-consuming asynchronous operations... 4 dispatch_async (dispatch_get_main_queue (), ^ {5 // return to the main thread and execute the UI refresh operation 6}); 7 });
9. delayed execution
There are two common methods for iOS delayed execution.
[Self initialize mselector: @ selector (run) withObject: nil afterDelay: 2.0]; // call self's run method after 2 seconds
Dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t) (2.0 * NSEC_PER_SEC), dispatch_get_main_queue (), ^ {// The code here is executed asynchronously after 2 seconds ...});
10. One-time code
The dispatch_once function ensures that a piece of code is executed only once during the program running.
1 static dispatch_once_t onceToken; 2 dispatch_once (& onceToken, ^ {3 // code executed only once (thread-safe by default) 4 });
11. Queue Group
There is such a requirement
First, perform two time-consuming operations asynchronously.
Second, after two asynchronous operations are completed, return to the main thread to execute the operation.
If you want to quickly and efficiently implement the above requirements, you can use the queue Group
1 dispatch_group_t group = dispatch_group_create (); 2 dispatch_group_async (group, dispatch_get_global_queue (queue, 0), ^ {3 // execute 1 time-consuming Asynchronous Operation 4 }); 5 dispatch_group_async (group, dispatch_get_global_queue (queue, 0), ^ {6 // execute 1 time-consuming Asynchronous Operation 7}); 8 dispatch_group_quey (group, dispatch_get_main_queue (), ^ {9 // after all the preceding asynchronous operations are completed, return to the main thread... 10 });
12. Singleton Mode
The Singleton mode ensures that a class has only one instance while the program is running, and the instance is easy for external access. This allows you to easily control the number of instances and save system resources.
The Singleton mode varies in the ARC \ MRC environment and requires two sets of different codes.
Macro can be used to determine whether it is an ARC environment
#if __has_feature(objc_arc)// ARC#else// MRC#endif
Implementation of Singleton mode in ARC:
1. Keep a Global static instance in. m.
static id _instance;
2. Override allocWithZone: method. Create a unique instance here (pay attention to thread security)
1 + (id)allocWithZone:(struct _NSZone *)zone2 {3 @synchronized(self) {4 if (!_instance) {5 _instance = [super allocWithZone:zone];6 }7 }8 return _instance;9 }
3. Provides a class method to allow external access to a unique instance.
1 + (instancetype)sharedSoundTool2 {3 @synchronized(self) {4 if (!_instance) {5 _instance = [[self alloc] init];6 }7 }8 return _instance;9 }
Non-ARC (MRC), Singleton mode implementation (several more steps than ARC)
1. Implement copyWithZone: Method
1 + (id)copyWithZone:(struct _NSZone *)zone2 {3 return _instance;4 }
2. Memory Management
1 - (id)retain { return self; }2 - (NSUInteger)retainCount { return 1; }3 - (oneway void)release {}4 - (id)autorelease { return self; }
Iv. NSOperation
NSOperation:
With NSOperation and NSOperationQueue, you can also implement multi-threaded programming.
The procedure for implementing multiple threads in NSOperation and NSOperationQueue is as follows:
- Encapsulate the operation to be executed into an NSOperation object.
- Then add the NSOperation object to the NSOperationQueue.
- The system will automatically put the operations encapsulated in NSOperation into a new thread for execution.
1. NSOperation subclass
NSOperation is an abstract class and does not have the ability to encapsulate operations. It must be used as a subclass.
There are three ways to use NSOperation subclass:
- NSInvocationOperation
- NSBlockOperation
- The custom subclass inherits NSOperation and implements corresponding internal methods.
NSInvocationOperation
Create NSInvocationOperation object
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
Call the start method to start the operation.
- (void)start;
Once the operation is performed, the target's sel method will be called.
Note:
- By default, after the start method is called, a new thread is not opened to execute the operation, but the operation is executed synchronously in the current thread.
- The operation is performed asynchronously only when NSOperation is put in an NSOperationQueue.
NSBlockOperation
Create an NSBlockOperation object
+ (id)blockOperationWithBlock:(void (^)(void))block;
Add more operations using addExecutionBlock:
- (void)addExecutionBlock:(void (^)(void))block;
Note: As long as the NSBlockOperation encapsulation operand is greater than 1, the operation will be executed asynchronously.
2. NSOperationQueue
NSOperationQueue: NSOperation can call the start method to execute the task, but it is executed synchronously by default. If you add NSOperation to NSOperationQueue (Operation Queue), the system will automatically perform operations in NSOperation asynchronously.
Add operation to NSOperationQueue
- (void)addOperation:(NSOperation *)op;- (void)addOperationWithBlock:(void (^)(void))block;
2.1 Max concurrency
The number of concurrent tasks. For example, if three threads are enabled to execute three tasks at the same time, the number of concurrent jobs is three.
Related methods for maximum concurrency
- (NSInteger)maxConcurrentOperationCount;- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
3. Queue cancellation, suspension, and recovery
Cancel all queue operations
- (void)cancelAllOperations;
You can also call the-(void) cancel Method of NSOperation to cancel a single operation.
Suspend and restore a queue
-(Void) setsuincluded :( BOOL) B; // YES indicates that the queue is suspended; NO indicates that the queue is restored-(BOOL) issuincluded;
4. Operation priority
Sets the priority of NSOperation in the queue to change the operation execution sequence.
- (NSOperationQueuePriority)queuePriority;- (void)setQueuePriority:(NSOperationQueuePriority)p;
Value of priority (the higher the priority, the more advanced the execution)
NSOperationQueuePriorityVeryLow = -8L,NSOperationQueuePriorityLow = -4L,NSOperationQueuePriorityNormal = 0,NSOperationQueuePriorityHigh = 4,NSOperationQueuePriorityVeryHigh = 8
5. Operation dependency
Dependencies can be set between NSOperation to ensure the execution sequence. For example, Operation B can be executed only after operation A is executed. You can write this statement as follows:
[OperationB addDependency: operationA]; // operation B depends on operation
You can create dependencies between NSOperation of different queue.
Note: Do not depend on each other. For example, A depends on B and B depends on.
6. Operation execution sequence
For the operations added to the queue, their execution order depends on 2 points:
- First, according to the dependency between NSOperation
- Then, according to the NSOperation priority
Therefore, the overall execution order is: first satisfy the dependency, and then select the execution with the highest priority from NSOperation.
7. Custom NSOperation
The procedure for customizing NSOperation is simple.
Override-(void) main method to implement the task to be executed
Override-note of (void) main method
- Create an automatic release pool by yourself (because the automatic release pool of the main thread cannot be accessed for asynchronous operations)
- The-(BOOL) isCancelled method is often used to check whether the operation is canceled and respond to the cancellation.