我正在做這個多線程應用程序,看看@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:'上,你會看到當前線程不是主線程。 –