A Nsthread object that represents a thread below is a way for nsthread to open threads
- (void) Touchesbegan: (Nsset<uitouch *> *) touches withevent: (Uievent *)Event{[Self openthreadwithnsthread]; [Nsthread Mainthread];//get the main thread[Nsthread CurrentThread];//gets the current thread}- (void) Openthreadwithnsthread {/** First parameter target object self * Second parameter method selector called method * The third argument before the method that you call to pass the parameter can be nil*/ //The first wayNsthread *thread = [[Nsthread alloc] initwithtarget:self selector: @selector (threadaction:)Object:@"ABC"]; Thread.Name=@"Thread 1"; //0.0-1.0 between 1.0 up to 0.0 minimum default 0.5 higher threads are called more frequentlyThread.threadpriority =1.0; [Thread start];//you need to call the startup thread manually//The second way[Nsthread detachnewthreadselector: @selector (threadaction:) totarget:self withobject:@"ABC2"];//Auto-start thread//The Third Way[Self Performselectorinbackground: @selector (threadaction:) Withobject:@"open a background thread"];//open a background thread//Block ModeNsthread *thread1 = [[Nsthread alloc] initwithblock:^{NSLog (@"%@", [Nsthread CurrentThread]); }]; Thread1.name=@"Thread 2"; Thread1.threadpriority=0.5; [Thread start]; //or[Nsthread detachnewthreadwithblock:^{NSLog (@"%@", [Nsthread CurrentThread]); }]; }- (void) Threadaction: (NSString *)params{NSLog (@"%@ and%@",params, [Nsthread currentthread].name);}
Nsthread creating a thread's life cycle
The thread is freed when the task in the thread finishes executing can inherit Nsthread create a new class override Dealloc method to validate
The state of the thread
When the thread is in the ready state, the thread is moved to the scheduler thread pool (the CPU only dispatches threads within this thread pool), and when it is in a blocking state, the thread is moved out of the scheduler thread pool, and then the pool is moved out of memory when it is in a dead state.
- (void) Threadstatus {//Create thread create a thread in memory (new state)Nsthread *thread = [[Nsthread alloc] initwithtarget:self selector: @selector (ThreadAction1)Object: nil]; [Thread start]; //The ready state will be put down. The thread pool inside the friend can be dispatched by the CPU only if it is in the scheduler thread pool. }//once the thread dies, you can't start the task again.- (void) ThreadAction1 {//Running State for(Nsinteger i =0; I <10000; i + +) { if(i = = the) { //[Nsthread sleepuntildate:[nsdate datewithtimeintervalsincenow:2.0];[Nsthread Sleepfortimeinterval:2.0];//blocking state moves the pool of outgoing threads//two seconds to go into ready state again wait for dispatch to go into run state } if(i = =8000) { //Break ;//Mission accomplished natural death[Nsthread exit];//revoke thread forced into death state} NSLog (@"%@", [Nsthread CurrentThread]); } //death status after executing method}
Thread security is also very important here a method is introduced that will focus on the following
The security hidden trouble of multithreading
Resource sharing
1 blocks of resources may be shared by multiple threads, that is, multiple threads may access the same piece of resources, such as multiple threads accessing the same object in the same variable the same file can easily cause data confusion and data security problems at this time.
Analysis of the cause of safety hazard
Solutions to security risks
Problem code
#import "ViewController.h"@interfaceViewcontroller () @property (nonatomic,strong) Nsthread*threada;//Conductor a@property (Nonatomic,strong) Nsthread *threadb;//Conductor B@property (Nonatomic,strong) Nsthread *THREADC;//Conductor C@property (nonatomic,assign) Nsinteger totalcount;@end@implementationViewcontroller- (void) Touchesbegan: (Nsset<uitouch *> *) touches withevent: (Uievent *)Event { //set total number of votesSelf.totalcount = +; Self.threada= [[Nsthread alloc] initwithtarget:self selector: @selector (Saleticket)Object: nil]; Self.threadA.name=@"Conductor a"; [Self.threada start]; SELF.THREADB= [[Nsthread alloc] initwithtarget:self selector: @selector (Saleticket)Object: nil]; Self.threadB.name=@"Conductor B"; [Self.threadb start]; SELF.THREADC= [[Nsthread alloc] initwithtarget:self selector: @selector (Saleticket)Object: nil]; Self.threadC.name=@"Conductor C"; [SELF.THREADC start];}//Ticketing- (void) Saleticket { while(1) {Nsinteger count=Self.totalcount; if(Count >0) { for(Nsinteger i =0; I <100000; i + +) { } //sell a ticket.Self.totalcount = count-1; NSLog (@"%@ sell a ticket and%zd ticket.", [Nsthread currentthread].name,self.totalcount); }Else{NSLog (@"The tickets are sold out."); Break; } } }
Print results
2018-Geneva- to A: -:38.600491+0800nsthreaddemo[1016:86284"Conductor a sold a ticket and 999 tickets left."2018-Geneva- to A: -:38.600493+0800nsthreaddemo[1016:86285] Conductor B sold a ticket and 999 tickets left.2018-Geneva- to A: -:38.600519+0800nsthreaddemo[1016:86286] Conductor C sold a ticket and 999 tickets left.
Problem Solving Code
#import "ViewController.h"@interfaceViewcontroller () @property (nonatomic,strong) Nsthread*threada;//Conductor a@property (Nonatomic,strong) Nsthread *threadb;//Conductor B@property (Nonatomic,strong) Nsthread *THREADC;//Conductor C@property (nonatomic,assign) Nsinteger totalcount;@end@implementationViewcontroller- (void) Touchesbegan: (Nsset<uitouch *> *) touches withevent: (Uievent *)Event { //set total number of votesSelf.totalcount = +; Self.threada= [[Nsthread alloc] initwithtarget:self selector: @selector (Saleticket)Object: nil]; Self.threadA.name=@"Conductor a"; [Self.threada start]; SELF.THREADB= [[Nsthread alloc] initwithtarget:self selector: @selector (Saleticket)Object: nil]; Self.threadB.name=@"Conductor B"; [Self.threadb start]; SELF.THREADC= [[Nsthread alloc] initwithtarget:self selector: @selector (Saleticket)Object: nil]; Self.threadC.name=@"Conductor C"; [SELF.THREADC start];}//Ticketing- (void) Saleticket { while(1) { //the lock must be globally unique@synchronized (self) {Nsinteger count=Self.totalcount; if(Count >0) { for(Nsinteger i =0; I <100000; i + +) { } //sell a ticket.Self.totalcount = count-1; NSLog (@"%@ sell a ticket and%zd ticket.", [Nsthread currentthread].name,self.totalcount); }Else{NSLog (@"The tickets are sold out."); Break; } } } }
Advantages and disadvantages of mutual exclusion lock
Advantages: It can effectively prevent the data security problem caused by multi-thread snatch resource
Cons: Consumes a lot of CPU resources
Use of mutexes: Multiple threads rob the same piece of resources
Related jargon: Thread synchronization, multiple threads performing tasks sequentially
Mutex is the use of thread synchronization technology
Atomic and non-atomic properties
OC has nonatomic and atomic two choices when defining attributes
Atomic: Atomic attribute, locking for setter method (default is Atomic)
Nonatomic: Non-atomic attribute, does not lock the setter method
1 int Age ; 2 3 -(void) Setage: (int) Age456 7 _age = Age ; 8 }9}
Selection of atomic and non-atomic properties
Comparison of Nonatomic and atomic
Atomic: Thread safety, which requires a lot of resources (not really thread-safe, more accurately, read-write security, but not thread-safe, because other threads can do things other than read and write.) Thread safety needs to be guaranteed by the developer itself. )
Nonatomic: Non-thread-safe, suitable for small memory mobile devices
Recommendations for iOS development
All properties are declared as Nonatomic
Try to avoid multiple threads robbing the same piece of resources
As far as possible to locking, resource-grabbing business logic to the server-side processing, reduce the pressure of mobile clients
Basic use of IOS multi-thread Nsthread