2013-07-01 37 views
2

我有一個非常簡單的問題,我希望有人能指出我在正確的方向。我是一名Java開發人員,試圖找出正確的客觀C方法來實現全局鎖定。我有一個在幾個地方實例化的類。每個實例讀取和寫入一個單一的通用文件。因此,我需要確保這個類中的所有方法調用都是原子的。整個班級鎖定目標C

static Object lock 

public void writeToFile(){ 
    synchronized(lock){ 
     //thread safe code goes here 
    } 
} 

靜態標識符將意味着,鎖定對象在所有實例共享,並會因此是線程:在Java如下這將被完成。不幸的是,由於iOS沒有類似的變量,我不確定實現這個功能的最佳方式是什麼。

+0

注:我試圖做@synchronized(self.class),沒有任何抱怨,但我不是100%確定這是正確的方法來解決這個問題? – akhalsa

+1

@synchronized(self.class)'確實可以工作並阻止該類的所有對象。如果你只是想鎖定這個實例,請改用'@synchronized(self)'。如果您需要非阻塞鎖,請參閱http://stackoverflow.com/questions/17396945/how-do-i-check-if-an-object-is-being-synchronized/17399427#17399427 –

回答

4

如果你想要的只是一個簡單的全局鎖,請看看NSLock。

如:

static NSLock * myGlobalLock = [[NSLock alloc] init]; 

if ([myGlobalLock tryLock]) { 
    // do something 
    [myGlobalLock unlock]; 
} 
else { 
    // couldn't acquire lock 
} 

然而,這是怎麼回事,因爲它需要一個內核調用會導致性能下降。如果你想序列化資源的訪問,使用Grand Central Dispatch和一個專用隊列會更好 - 這些都是在不需要內核中斷的情況下調度的。

如:

// alloc a dispatch queue for controlling access to your shared resource 
static dispatch_queue_t mySharedResourceQueue = nil; 
static dispatch_once_t onceToken; 
dispatch_once(&onceToken, ^{ 
    mySharedResourceQueue = dispatch_queue_create("com.myidentifier.MySharedResourceQueue", DISPATCH_QUEUE_SERIAL); // pick a unique identifier 
}); 
// don't forget to call dispatch_release() to clean up your queue when done with it! 

// to serialize access to your shared resource and block the current thread... 
dispatch_sync(mySharedResourceQueue, ^{ 
    // access my shared resource 
}); 

// or to access it asynchronously, w/o blocking the current thread... 
dispatch_async(mySharedResourceQueue, ^{ 
    // access my shared resource 
}); 

調度隊列是非常真棒的東西,如果你要到iOS開發,你應該學會如何在爲了與強大的性能應用程序中使用它們。

除了NSLock之外,還有不同類型的鎖。閱讀上以獲取更多信息線程編程基準同步...

線程編程參考: https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html#//apple_ref/doc/uid/10000057i

NSLock參考: https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSLock_Class/Reference/Reference.html

大中央調度參考:https://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

+2

中給出的答案該隊列應該使用明確的DISPATCH _.._ SERIAL選項創建。 – bbum

+0

來自Apple的文檔:「默認情況下,使用dispatch_queue_create()創建的隊列等待先前出列的塊完成,然後出隊下一個塊。此FIFO完成行爲有時被簡單描述爲」串行隊列「。」 –

+1

當然 - 但這並不意味着你不應該在你的代碼中明確表示。更明確的併發代碼對於某個新人(包括自己現在六個月以後)更容易維護它。顯然,這是一個無法改變的默認行爲,但爲什麼讓未來的維護人員查找該行爲? – bbum