2011-12-21 36 views
1

我无法找到任何实例如何处理相同的(类)变量当使用操作队列。在C &线程它关于互斥体。所以,当NSOperationQueue启动一个线程操作和类变量被修改时会发生什么?线程安全吗?谢谢。线程安全:NSOperationQueue + [阵列ADDOBJECT]

@interface MyTest { 
    NSMutableArray *_array; 
} 
@end 

-(id)init 
{ 
    ... 
    _array = [NSMutableArray new]; // class variable 

     // queue time consuming loading 
    NSOperationQueue *queue = [NSOperationQueue new]; 
    NSInvocationOperation *operation = 
     [NSInvocationOperation initWithTarget:self 
            selector:@selector(populate) 
             object:nil]; 
    [queue addOperation:operation]; 

     // start continuous processing 
    [NSTimer scheduledTimerWithTimeInterval:0.1 
            target:self 
            selector:@selector(processing) 
            userInfo:nil 
            repeats:YES]; 
    ... 
} 

-(void)populate 
{ 
    while (...) 
    { 
     id element = ...; // time consuming 

      // modify class variable "_array" from operation's thread (?) 
     [_array addObject:element]; 

      // Ok, I can do instead of addObject 
      // performSelectorOnMainThread:withObject:waitUntilDone: 
      // but is it the only way? Is it needed? 
    } 
} 

    // access and/or modify class variable "_array" 
-(void)processing 
{ 
    NSLog(@"array.count = %d", array.count); 
    for (id i in _array) 
    { 
     [_array addObject:[NSNumber numberWithInt:rand() % 100]]; 
      // etc... 
    } 
} 

回答

1

不,这不是线程安全的,如果你启动一个线程,做一个类变量,可以通过一些其他的线程修改那么它不是线程安全的一些工作,如果处理是从某个线程同时调用填充另一个正在运行,则当foreach循环看到该阵列已被修改,你可能会得到一个例外,但你会得到异常反正你要修改的foreach循环内的数组中的例子(你不应该这样做,程序会抛出一个异常)......解决这个问题的一种方法是使用数组上的同步块,它将确保同步块不会同时执行,线程会阻塞,直到一个同步块结束,例如

-(void)populate 
    { 


     while (...) 
     { 
      id element = ...; // time consuming 

       // modify class variable "_array" from operation's thread (?) 
     @synchronized(_array) 
     { 
      [_array addObject:element]; 

     }   // Ok, I can do instead of addObject 
       // performSelectorOnMainThread:withObject:waitUntilDone: 
       // but is it the only way? Is it needed? 
     } 

    } 

     // access and/or modify class variable "_array" 
    -(void)processing 
    { 


      @synchronized(_array) 
     { 
      NSLog(@"array.count = %d", array.count); 
      for (id i in _array) 
      { 
       //you shouldnt modify the _array here you will get an exception 
        // etc... 
      } 
     } 
    } 
+0

好吧,这是显而易见的。为什么这不是苹果公司的网站上写的ConcurrencyProgrammingGuide(一个有关Operations /队列)?我的意思是,这是我第一次看到'@ synchronized'。我现在看到,它在关于线程的部分中进行了描述。 – debleek63 2011-12-22 00:03:47

+0

你认为什么是更好的做法:使用'@ synchronized'或调用'performSelectorOnMainThread'? – debleek63 2011-12-22 00:05:28

+0

另一件事:是否声明/访问'_array'为'atomic'属性? – debleek63 2011-12-22 00:07:15