多线程

  1. 主线程的生命周期和程序的生命周期一样.
  2. NSTimer不能在子线程上执行.
  3. 状态:创建->等待->运行->销毁->死亡.(另还有阻塞)

NSRunLoop:主循环,可以控制任何线程。

NSThread:自己管理状态,最复杂。

Cocoa NSOperation:

----------------------------------------------------------------------------------------------------

RootViewController.m

#import "RootViewController.h"

@interface RootViewController ()
{
    int count;
    int ticketNumber;
    NSLock *lock;
}
@end

@implementation RootViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    
//    [self mA];
    
    count = 100;
    ticketNumber = 0;
    lock = [[NSLock alloc]init];
    
    NSThread *t1 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
    t1.name = @"窗口1";
    [t1 start];
    
    NSThread *t2 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
    t2.name = @"窗口2";
    [t2 start];
    
    NSThread *t3 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
    t3.name = @"窗口3";
    [t3 start];
    
  
}
#pragma mark -NSThead的应用-
-(void)saleTicket
{
    while (1)
    {
        [lock lock];
        if (count > 0)
        {
            count = 100 - ticketNumber;
            NSLog(@"%@卖出第%d张票,剩余%d张票",[NSThread currentThread].name,ticketNumber,count);
            ticketNumber++;
        }
        else
        {
            [lock unlock];
            break;
        }
        [lock unlock];
    }
}
#pragma make -1-
-(void)mA
{
    
    //oc中线程创建
    /*
    //NSThread
    NSThread *t = [[NSThread alloc]initWithTarget:self
                                         selector:@selector(threadMethod)
                                           object:nil];
    [t start];
    */
    //    [self threadMethod];
    //2
//    [NSThread detachNewThreadSelector:@selector(threadMethod) toTarget:self withObject:nil];
    /*
    //3
    NSOperation *operation = [[NSOperation alloc]init];
    [operation setCompletionBlock:^{
        for (int i = 0; i < 10; i++)
        {
            NSLog(@"新线程打印%d",i);
        }
    }];
    [operation start];
     */
    /*
    //4
    [self performSelectorInBackground:@selector(threadMethod) withObject:nil];
    //回到主线程
//    [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
    //在哪个线程上执行
//    [self performSelector:<#(SEL)#> onThread:<#(NSThread *)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>]
     */
    //5.比较常用
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    //可设置并发数,第一次并发多少个,下一次
    queue.maxConcurrentOperationCount = 1;

    NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(threadMethod) object:nil];
    //当CUP的资源不够时,可设置优先级,够的话,不影响优先级
    [op setQueuePriority:NSOperationQueuePriorityVeryLow];
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(threadMethod2) object:nil];
    //当CUP的资源不够时,可设置优先级,够的话,不影响优先级
    [op2 setQueuePriority:NSOperationQueuePriorityVeryHigh];
    [queue addOperation:op];
    [queue addOperation:op2];
    //6.GCD
    
    [self mB];
    
}
-(void)mB
{
    for (int i = 0; i < 10; i++)
    {
        NSLog(@"主线程打印%d",i);
    }
}
-(void)threadMethod
{
    for (int i = 0; i < 10; i++)
    {
        NSLog(@"新线程打印%d",i);
    }
}
-(void)threadMethod2
{
    for (int i = 0; i < 10; i++)
    {
        NSLog(@"新线程2打印%d",i);
    }
}
@end

 ---------------------------------------------------------------------------------------------

 

2.ImageOperation.h(自定义请求图片的线程Operation)参考资料:http://c.gzl.name/archives/137

/*自定义NSOperation*/
@interface ImageOperation : NSOperation
@property(nonatomic,assign)id target;
@property(nonatomic,assign)SEL selector;
@property(nonatomic,retain)NSString *imageURLString;

-(id)initWithTarget:(id)target
          andAction:(SEL )selector
       andimageURLString:(NSString *)imageURLString;
@end

ImageOperation.m (走完初始化init方法之后自动会走main方法)

#import "ImageOperation.h"

@implementation ImageOperation
-(id)initWithTarget:(id)target andAction:(SEL)selector andimageURLString:(NSString *)imageURLString
{
    if (self = [super init])
    {
        self.target = target;
        self.selector = selector;
        self.imageURLString = imageURLString;
    }
    return self;
}

-(void)main
{
    if ([self isCancelled])
    {
        return;
    }
    UIImage *image = [UIImage imageWithData:
                      [NSData dataWithContentsOfURL:
                       [NSURL URLWithString:self.imageURLString]]];

   [self.target performSelectorOnMainThread:self.selectorwithObject:image waitUntilDone:NO];//将image作参数传到self.selector方法中,image即self.target(作用绑定-initWithTarget:....)

    if ([self isCancelled])
    {
        return;
    }
}
@end

RootViewController.h

@interface RootViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIButton *GCDdownLoadBtn;

@property (weak, nonatomic) IBOutlet UIButton *downloadBtn;
@property (weak, nonatomic) IBOutlet UIImageView *headImageView;
-(IBAction)downLoad:(id)sender;
-(IBAction)GCDdownLoad:(id)sender;
@end

RootViewController.m

#import "RootViewController.h"
#import "ImageOperation.h"
@implementation RootViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
  
}

-(IBAction)downLoad:(id)sender
{
    /*
    NSOperation *operation = [[NSOperation alloc]init];
    [operation setCompletionBlock:^{
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic.6188.com/upload_6188s/flashAll/s800/20120827/1346029443Rd9sjm.jpg"]];
        //ui要在主线程实现
        UIImage *image = [UIImage imageWithData:data];
        [self.headImageView performSelectorOnMainThread:@selector(setImage:) withObject:image  waitUntilDone:NO];
    } ];
    [operation start];
    */
    /*
    //2没有写blcok就需要放到队列里才会异步
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    NSInvocationOperation *io = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(InvocationOperationDownload:) object:nil];
    [queue addOperation:io];
     */
    //3
   
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    ImageOperation *imageOperation = [[ImageOperation alloc]initWithTarget:self andAction:@selector(refreshUI:)   andimageURLString:@"http://pic.6188.com/upload_6188s/flashAll/s800/20120827/1346029443Rd9sjm.jpg"];
    [queue addOperation:imageOperation];
    
}
#pragma mark -3-
-(void)refreshUI:(UIImage *)image//因为self是image,所以这里的参数是UIImage
{
    [self.headImageView performSelectorOnMainThread:@selector(setImage:)  withObject:image waitUntilDone:NO];//给imageView设置image
}


#pragma mark -2-
-(void)InvocationOperationDownload:(NSInvocationOperation *)sender
{
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic.6188.com/upload_6188s/flashAll/s800/20120827/1346029443Rd9sjm.jpg"]];
    //ui要在主线程实现
    UIImage *image = [UIImage imageWithData:data];
    [self.headImageView performSelectorOnMainThread:@selector(setImage:) withObject:image  waitUntilDone:NO];
}
#pragma mark -4-
-(IBAction)GCDdownLoad:(id)sender
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://f.hiphotos.baidu.com/image/w%3D1366%3Bcrop%3D0%2C0%2C1366%2C768/sign=334e29095143fbf2c52ca2208648f1e3/f603918fa0ec08faa42f1fa65bee3d6d55fbda80.jpg"]];
        //ui要在主线程实现
        UIImage *image = [UIImage imageWithData:data];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.headImageView.image = image;
        });
    });
}
@end

 ----------------------------------------------------------------------------------------------

3.NSRunLoop

RootViewController.m

#import "RootViewController.h"

@interface RootViewController ()
{
    int count;
}
@end

@implementation RootViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    /*如何提高NSTimer的准确性*/
    count = 0;
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
     NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(threadMethod) object:nil];
    [queue addOperation:op];
}
-(void)threadMethod
{
    @autoreleasepool
    {
        [NSTimer scheduledTimerWithTimeInterval:0.1
                                         target:self
                                       selector:@selector(print:)
                                       userInfo:nil
                                        repeats:YES];
    }
    /*NSRunLoop是线程相关基础框架的一部分,一个runLoop就是一个事件处理机制的循环,它可以不停的调度任务以及处理输入事件
     ,NSRunLoop可以保持一个线程处于活动状态,不会被销毁*/
    [[NSRunLoop currentRunLoop]run];//主线程也有一个runloop,测试?计时器放在多线程下可以提高准确性,游戏需要
    NSLog(@"runloop stop");
}

-(void)print:(NSTimer *)sender
{
    if (count == 10)
    {
        [sender invalidate];
    }
    
    NSLog(@"hello world %d",count++);
    
}
@end

 4.

CustomCell.h

@interface CustomCell : UITableViewCell
@property(nonatomic,retain)UIImageView *downImageView;
@property(nonatomic,retain)NSString *imageViewUrlStr;
-(void)loadImageWithQueue:(NSOperationQueue *)queue;
@end

Custom.m

#import "CustomCell.h"

@implementation CustomCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self)
    {
        self.downImageView = [[[UIImageView alloc]initWithFrame:CGRectMake(10, 0, 100, 100)]autorelease];
        [self.contentView addSubview:self.downImageView];
    }
    return self;
}
-(void)setContentInCellWithModel:(NSString *)str
{
//    self.downImageView.image
}
-(void)loadImageWithQueue:(NSOperationQueue *)queue//将加载图片的线程加入外面的队列中
{
    NSInvocationOperation *iop = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downLoad) object:nil];
    [queue addOperation:iop];
    [iop release];
}
-(void)downLoad
{
    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.imageViewUrlStr]]];
    [self.downImageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
}
-(void)down
{
//    [NSURLConnection connectionWithRequest:<#(NSURLRequest *)#> delegate:self];
}
@end

RootViewController.h

@interface RootViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
{
    NSMutableArray *dataSource;
    NSOperationQueue *queue;
}
@end

RootViewController.m

#import "RootViewController.h"
#import "CustomCell.h"

@implementation RootViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    dataSource = [[NSMutableArray alloc]initWithObjects:@"http://f.hiphotos.baidu.com/image/w%3D2048/sign=24dfaa86d2a20cf44690f9df42314a36/95eef01f3a292df59da38114be315c6034a8734a.jpg",
                  @"http://a.hiphotos.baidu.com/image/w%3D2048/sign=5c4c05ef8fb1cb133e693b13e96c574e/f9dcd100baa1cd111a6f1c20bb12c8fcc2ce2dd0.jpg",
                  @"http://b.hiphotos.baidu.com/image/w%3D2048/sign=0968c735347adab43dd01c43bfecb21c/503d269759ee3d6da48af3d641166d224f4ade5b.jpg",
                  @"http://a.hiphotos.baidu.com/image/w%3D2048/sign=8214ba3fbb12c8fcb4f3f1cdc83b9345/ac4bd11373f08202aa30592049fbfbedab641b0b.jpg",
                  @"http://c.hiphotos.baidu.com/image/w%3D2048/sign=4de426e7b68f8c54e3d3c22f0e112cf5/314e251f95cad1c845331c2e7d3e6709c93d512b.jpg",
                  @"http://d.hiphotos.baidu.com/image/w%3D2048/sign=d2714dddc2cec3fd8b3ea075e2b0d53f/72f082025aafa40f20987eccaa64034f78f01940.jpg",
                  @"http://c.hiphotos.baidu.com/image/w%3D2048/sign=3f69322892ef76c6d0d2fc2ba92efcfa/b03533fa828ba61e726728264334970a304e592a.jpg",
                  @"http://b.hiphotos.baidu.com/image/w%3D2048/sign=6a784b289113b07ebdbd570838ef9023/e61190ef76c6a7ef5f91642ffffaaf51f3de6600.jpg",
                  @"http://f.hiphotos.baidu.com/image/w%3D2048/sign=c8ff7f2271f082022d92963f7fc3faed/b21c8701a18b87d642cb301e050828381f30fd22.jpg",
                  @"http://e.hiphotos.baidu.com/image/w%3D2048/sign=48e859cae4cd7b89e96c3d833b1c43a7/a8773912b31bb05164f6ea28347adab44bede0e4.jpg", nil];
    
    //
    UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStylePlain];
    [self.view addSubview:tableView];
    [tableView release];
    tableView.rowHeight = 100;
    tableView.delegate = self;
    tableView.dataSource = self;
    //
    queue = [[NSOperationQueue alloc]init];
    
}


#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return dataSource.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if (!cell)
    {
        cell = [[[CustomCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]autorelease];
        
    }
    cell.imageViewUrlStr = [dataSource objectAtIndex:indexPath.row];
    [cell loadImageWithQueue:queue];
    return cell;
}
@end

--------------------------------------------------------------------------------------------------------------------------------

GCD中央回调,队列式结构:多核技术,性能最高

  • 不可变对象通常是线程安全的。一旦你创建它们,您可以安全地通过这些对象和线程。另一方面,可变的对象通常不是线程安全的。使用可变的对象在线程的应用程序中,应用程序必须适当地同步。

1.线程问题:

  • 更新同一数据时,容易出现数据竞争,原因是并发而导致数据同时更新,线程不安全。该情况适合用同步,通常同一个文件、单独一个表、对同一个文件写东西就可以考虑用同步。
  • 同步的时候很容易出现死锁。
  • 开启多个线程会消耗大量内存。

2.自定义线程:要管理内存

串行队列:Serial Diapatch Queue.等待现在执行处理结束

并行队列:Concurrent Dispatch Queue.不等待现在执行中处理结束

3.系统线程:不用管理内存

Main Diapatch Queue属于Serial Diapatch Queue类型

Global Diapatch Queue属于Concurrent Dispatch Queue类型,有4个优先级

Demo1---------------------------------------------------------自定义线程

//1自定义线程创建
    dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);//第一个参数Serial Dispatch Queue的名称id.第二个参数NULL表示是Serial的,相反DISPATCH_QUEUE_CONCURRENT
    dispatch_release(mySerialDispatchQueue);
    dispatch_retain(mySerialDispatchQueue);
    //2自定义线程变更优先级方法
    dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_set_target_queue(mySerialDispatchQueue, globalDispatchQueueBackground);

Demo2---------------------------------------------------------线程组,并发执行

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    


    dispatch_group_async(group, queue, ^
    {
        NSLog(@"one");
    });
    dispatch_group_async(group, queue, ^
    {
        NSLog(@"two");
    });
    dispatch_group_async(group, queue, ^
    {
        NSLog(@"three");
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^
    {
        NSLog(@"done");
    });

 控制台输出结果:

2014-07-18 05:18:11.351 MutThreadDemo[2999:3507] two
2014-07-18 05:18:11.351 MutThreadDemo[2999:3803] three
2014-07-18 05:18:11.350 MutThreadDemo[2999:1303] one
2014-07-18 05:18:11.398 MutThreadDemo[2999:60b] done

Demo3---------------------------------------------------------异步并行队列

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^
    {
         NSLog(@"one");
    });
    dispatch_async(queue, ^
    {
        NSLog(@"two");
    });
    dispatch_async(queue, ^
    {
        NSLog(@"three");
    });
    dispatch_async(queue, ^
    {
        NSLog(@"four");
    });

控制台结果:

2014-07-18 05:16:28.091 MutThreadDemo[2977:3507] two
2014-07-18 05:16:28.091 MutThreadDemo[2977:3803] three
2014-07-18 05:16:28.091 MutThreadDemo[2977:1303] one
2014-07-18 05:16:28.091 MutThreadDemo[2977:3903] four

 Demo4---------------------------------------------------------同步并行队列

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_sync(queue, ^
    {
        NSLog(@"hello1");
    });
    dispatch_sync(queue, ^
    {
        NSLog(@"hello2");
    });
    dispatch_sync(queue, ^
    {
         NSLog(@"hello3");
    });
    dispatch_sync(queue, ^
    {
        NSLog(@"hello4");
                  });
    dispatch_sync(queue, ^
    {
        NSLog(@"hello5");
    });

控制台输出结果:

2014-07-18 05:36:24.841 MutThreadDemo[3214:60b] hello1
2014-07-18 05:36:24.841 MutThreadDemo[3214:60b] hello2
2014-07-18 05:36:24.842 MutThreadDemo[3214:60b] hello3
2014-07-18 05:36:24.842 MutThreadDemo[3214:60b] hello4
2014-07-18 05:36:24.843 MutThreadDemo[3214:60b] hello5

 Demo5---------------------------------------------------------并发处理数组类对象

 NSArray *array = [NSArray arrayWithObjects:@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9", nil];
//并发处理数组类对象
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^
    {
        dispatch_apply([array count], queue, ^(size_t index)
        {
            NSLog(@"%zu: %@",index,[array objectAtIndex:index]);
        });
        dispatch_async(dispatch_get_main_queue(), ^
        {
            NSLog(@"done");
        });
    });

打印结果:

2014-07-18 06:00:08.645 MutThreadDemo[3456:3803] 1: 1
2014-07-18 06:00:08.646 MutThreadDemo[3456:3a03] 3: 3
2014-07-18 06:00:08.646 MutThreadDemo[3456:3903] 2: 2
2014-07-18 06:00:08.645 MutThreadDemo[3456:1303] 0: 0
2014-07-18 06:00:08.649 MutThreadDemo[3456:3a03] 5: 5
2014-07-18 06:00:08.649 MutThreadDemo[3456:3803] 4: 4
2014-07-18 06:00:08.649 MutThreadDemo[3456:3903] 6: 6
2014-07-18 06:00:08.650 MutThreadDemo[3456:1303] 7: 7
2014-07-18 06:00:08.653 MutThreadDemo[3456:3a03] 8: 8
2014-07-18 06:00:08.654 MutThreadDemo[3456:3803] 9: 9
2014-07-18 06:00:08.665 MutThreadDemo[3456:60b] done

 Demo6---------------------------------------------------------控制线程队列

    dispatch_suspend(queue);//挂起线程
    dispatch_resume(queue);//重新恢复线程

Demo7----------------------------------------------------------并发串行队列

    //1自定义线程创建
    dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);//第一个参数Serial Dispatch Queue的名称id.第二个参数NULL表示是Serial的,相反DISPATCH_QUEUE_CONCURRENT
    dispatch_async(mySerialDispatchQueue, ^
    {
        NSLog(@"one");
    });
    dispatch_async(mySerialDispatchQueue, ^
    {
        NSLog(@"two");
    });
    dispatch_async(mySerialDispatchQueue, ^
    {
        NSLog(@"three");
    });
    dispatch_async(mySerialDispatchQueue, ^
    {
        NSLog(@"four");
    });

控制台打印结果:

2014-07-18 19:39:55.973 MutThreadDemo[486:1303] one
2014-07-18 19:39:55.973 MutThreadDemo[486:1303] two
2014-07-18 19:39:55.974 MutThreadDemo[486:1303] three
2014-07-18 19:39:55.974 MutThreadDemo[486:1303] four

Demo8---------------------------------------------------网络通信超时处理。因为GCD没有取消线程这个概念,只能用NSOperationQueue或者该处理方法。

    //发送请求的同时调回主线程开始计时
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    //设置定时为15秒后,允许延迟1秒
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, 15ull * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 1ull * NSEC_PER_SEC);
    
    dispatch_source_set_event_handler(timer, ^
    {
        //执行。。。
    
//执行完的后续处理。。。 dispatch_source_cancel(timer); }); dispatch_source_set_cancel_handler(timer, ^ { NSLog(@"释放资源"); // dispatch_release(timer); }); dispatch_resume(timer);//启动Dispatch Source定时

Demo9------------------------------------某段时间后执行----------------------

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull *NSEC_PER_SEC);//从现在时间开始,到3秒后.NSEC_PER_MSEC毫秒
    dispatch_after(time, dispatch_get_main_queue(), ^{
        NSLog(@"3秒后主线程执行");
    });

Demo10------------------------------------信号量同步处理----------------------

dispatch_semaphore_signal信号量+1

dispatch_semaphore_wait信号量-1

当信号量少于0的时候等待,大于等于0的时候,正常执行dispatch_semaphore_wait之后的内容

//通过信号量将线程异步转化为线程同步
    dispatch_semaphore_t dispatchSemaphore = dispatch_semaphore_create(0);
    //
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        NSLog(@"线程1");
        //发送信号量
        dispatch_semaphore_signal(dispatchSemaphore);
    });
    dispatch_async(queue, ^{
        //等待信号量,当发送信号量执行完并且2秒后才执行下一句代码
        dispatch_semaphore_wait(dispatchSemaphore, dispatch_time(DISPATCH_TIME_NOW, 2.0f* NSEC_PER_SEC));
        NSLog(@"线程2");
    });

.

2015-07-13 15:16:14.727 SemaphoreTest[6945:518077] 线程1
2015-07-13 15:16:14.727 SemaphoreTest[6945:518079] 线程2

Demo11------------------------------------将异步的线程分开2部分----------------------

dispatch_queue_t main = dispatch_get_main_queue();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
         NSLog(@"线程1");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"线程2");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"线程3");
    });
//    dispatch_group_notify(group, main, ^{
//        NSLog(@"main");
//    });
    //栅栏的作用
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    NSLog(@"part1完成");
    group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"线程4");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"线程5");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"线程6");
    });

.

2015-07-13 15:07:49.903 SemaphoreTest[6789:511201] 线程3
2015-07-13 15:07:49.903 SemaphoreTest[6789:511199] 线程2
2015-07-13 15:07:49.903 SemaphoreTest[6789:511200] 线程1
2015-07-13 15:07:49.904 SemaphoreTest[6789:511128] part1完成
2015-07-13 15:07:49.905 SemaphoreTest[6789:511199] 线程5
2015-07-13 15:07:49.905 SemaphoreTest[6789:511201] 线程6
2015-07-13 15:07:49.904 SemaphoreTest[6789:511200] 线程4

 .

dispatch_queue_t queue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"线程1");
        
    });
    dispatch_async(queue, ^{
        
        NSLog(@"线程2");
    });
    
    
    dispatch_async(queue, ^{
        NSLog(@"线程3");
        
    });
    dispatch_async(queue, ^{
        
        NSLog(@"线程4");
    });
    dispatch_barrier_async(queue, ^{NSLog(@"barrier");});
    dispatch_async(queue, ^{
        
        NSLog(@"线程5");
    });
    dispatch_async(queue, ^{
        
        NSLog(@"线程6");
    });
    dispatch_async(queue, ^{
        NSLog(@"线程7");
        
    });
    dispatch_async(queue, ^{
        
        NSLog(@"线程8");
    });

.

2015-07-13 15:22:53.511 SemaphoreTest[7067:524047] 线程3
2015-07-13 15:22:53.511 SemaphoreTest[7067:524049] 线程1
2015-07-13 15:22:53.511 SemaphoreTest[7067:524054] 线程4
2015-07-13 15:22:53.511 SemaphoreTest[7067:524046] 线程2
2015-07-13 15:22:53.512 SemaphoreTest[7067:524046] barrier
2015-07-13 15:22:53.512 SemaphoreTest[7067:524046] 线程5
2015-07-13 15:22:53.512 SemaphoreTest[7067:524054] 线程6
2015-07-13 15:22:53.512 SemaphoreTest[7067:524046] 线程7
2015-07-13 15:22:53.512 SemaphoreTest[7067:524054] 线程8

usleep(100000); //程序挂起,等待0.1

sleep(1);//程序挂起,等待1

同步处理

- (IBAction)start:(id)sender
{
    self.pageStillLoading = YES;
    [NSThread detachNewThreadSelector:@selector(loadPageInBackground:)toTarget:self withObject:nil];
    [self.progressLabel setHidden:NO];
    while (self.pageStillLoading) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
//        sleep(1);
    }
    [self.progressLabel setHidden:YES];
}

- (void)loadPageInBackground:(id)sender
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.pageStillLoading = NO;
    });
}

 

原文地址:https://www.cnblogs.com/huen/p/3625299.html