2011-12-21 64 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