我正在做这个多线程应用程序,看看@synchronized指令是如何工作的。我读过如果所有的线程都与@synchronized参数具有相同的对象,那么他们都等待相同所以我想用self作为参数,因为它对于所有线程都是一样的。
在这个应用程序中有一个文本字段被所有线程多次编辑。 我不关心性能,它只是一个测试所以我不把@synchronized指令放在for之前,但在它之内。简单的多线程应用程序有时会失败
我用的属性:
@property (weak) IBOutlet NSTextField *textField;
@property (nonatomic, copy) NSNumber* value;
@property (nonatomic,copy) NSMutableArray* threads;
代码:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
value= @0;
textField.objectValue= value;
for(int i=0; i<10; i++)
{
NSThread* thread=[[NSThread alloc]initWithTarget: self selector: @selector(routine:) object: nil];
[threads addObject: thread];
[thread start];
}
}
- (void) routine : (id) argument
{
for(NSUInteger i=0; i<100; i++)
{
@synchronized(self)
{
value= @(value.intValue+1);
textField.objectValue= value;
}
}
}
有时应用程序有成功,我看到1000作为文本字段value.But有时没有,我担心这是饥饿和我没有看到文本字段上的任何东西,它是空的。我尝试调试,但很难看到什么是错误的,因为失败的标准似乎对我来说是偶然的,有时它可以正常工作。
SOLUTION
@synthesize threads,value, textField;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
value= @0;
threads=[[NSMutableArray alloc]initWithCapacity: 100];
for(NSUInteger i=0; i<100; i++)
{
NSThread* thread=[[NSThread alloc]initWithTarget: self selector: @selector(routine:) object: nil ];
[threads addObject: thread];
[thread start];
}
}
- (void) routine : (id) arg
{
for(NSUInteger i=0; i<1000; i++)
{
@synchronized(self)
{
value= @(value.intValue+1);
[textField performSelectorOnMainThread: @selector(setObjectValue:) withObject: value waitUntilDone: NO];
}
}
}
这可能吗?我有没有发现一个好问题?还是我只是在做梦? (+1为一个有趣的问题。) – 2012-11-23 22:28:36
不知道..代码看起来好吗..但我不知道appkit的哪些部分是线程安全的... –
您添加的解决方案是不正确的。 [通知在同一个线程上发布和接收。](http://stackoverflow.com/questions/1004589/nsnotificationcenter-do-objects-receive-notifications-on-the-same-thread-they-a)设置一个断点在'-changeValue:'上,你会看到当前线程不是主线程。 –