线程安全:NSOperationQueue + [array addObject] [英] Thread safety: NSOperationQueue + [array addObject]

查看:211
本文介绍了线程安全:NSOperationQueue + [array addObject]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到任何例子如何处理相同(类)变量,当使用操作队列。在C&线程其关于互斥。那么,当 NSOperationQueue 启动一个操作线程并且类变量被修改时会发生什么?它是线程安全吗?谢谢。

I could not find any examples how to deal with the same (class) variable when operation queue is used. In C & threads its about mutexes. So, what happens when NSOperationQueue starts a thread for operation and class variable is modified? Is it thread safe? Thank you.

@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...
    }
}


推荐答案

不,这不是线程安全的,如果你启动一个线程做一些类变量的工作,可以修改一些其他线程,那么它的线程不安全,如果处理从一些线程而populate运行另一个,然后你可能会得到一个异常,当foreach循环看到数组已被修改,虽然你会得到那个异常,你正在修改foreach循环中的数组在你的示例中(你不应该,并且程序会抛出异常)...一种解决方法是使用数组上的同步块,它将确保同步块不会同时执行,线程块直到一个同步块完成,例如

No, this is not thread safe, if you start a thread that does some work on a class variable that can be modified by some other thread then its not thread safe, if processing is called from some thread while populate is running on another then you might get an exception when the foreach loop sees that the array has been modified, though you will get that exception anyway as you are modifying the array inside the foreach loop in your example (you shouldnt do that, and the program will throw an exception )... One way to get around this can be with a synchronized block on the array, it will ensure that the synchronized blocks wont be executed at the same time, the thread blocks until one synchronized block finishes, for example

    -(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...
            }
        }
    }

这篇关于线程安全:NSOperationQueue + [array addObject]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆