@synchronized()はObjective Cのシングルトンメソッドとして何をしますか?


87

シングルトンメソッドを作成したばかりですが、@synchronized()よく使うので関数の機能を知りたいのですが、意味がわかりません。

回答:


119

コードブロックの周りのクリティカルセクションを宣言します。マルチスレッドコードでは、@synchronized常に1つのスレッドのみがブロック内でそのコードを実行できることを保証します。

それが何をするのかわからない場合、アプリケーションはおそらくマルチスレッドではなく、おそらくそれを使用する必要はありません(特にシングルトン自体がスレッドセーフでない場合)。


編集: 2011年の元の回答にはなかった情報を追加します。

@synchronizedディレクティブによって保護されているコードの任意の領域に入るのを防止する複数のスレッド@synchronizedディレクティブ同じオブジェクトを参照します@synchronizedディレクティブに渡されるオブジェクトは、「ロック」として使用されるオブジェクトです。異なるオブジェクトがロックとして使用されている場合、2つのスレッドを同じ保護されたコード領域に含めることができます。また、同じオブジェクトをロックとして使用して、2つの完全に異なるコード領域を保護することもできます。

また、たまたまnilロックオブジェクトとして渡された場合、ロックはまったく取得されません。


14
重要なポイントがいくつかあります。1)nilポインターを使用@synchronizedしても何も起こりません。つまり、保護されないままになります。2)@synchronizedである遅いです
ホットリック2013

この回答は誤解を招くものであり、受け入れられる回答であってはなりません。それが言うことは時々正しいでしょうが(synhronizedに渡されたトークンがすべてのスレッドで同じオブジェクトである限り)、それは誤解を招くほど不完全です。同期は、「ブロック内のそのコード」だけでなく、関連付けられたコードセクションが同時に実行されるのを防ぎます。同期するパラメーターは、コードのどのセクション(または回答がそれらを呼び出すときの「ブロック」)を同時アクセスから保護するかを効果的に決定します。
アルダ

@アルダあなたは完全に正しいです。についてもう少し情報といくつかのAppleドキュメントへのリンクを追加しました@synchronized
John Calsbeek 2017年

@JohnCalsbeek、答えは今ではずっと良く見えます。私から親指を立てる。
アルダ2017年

@HotLicksはこれを指摘するのは興味深いですが、代替案(リンク?)を簡単に言うとさらに良いでしょう
itMaxence 2018年

43

ここここのアップルのドキュメントから:

@synchronizedディレクティブは、Objective-Cコードでその場でミューテックスロックを作成するための便利な方法です。@synchronizedディレクティブは、他のミューテックスロックと同じように機能します。つまり、異なるスレッドが同じロックを同時に取得するのを防ぎます。

ドキュメントには、このテーマに関する豊富な情報が記載されています。特に、何をしているのかわからずに使用していることを考えると、時間をかけて読む価値があります。


26

この@synchronizedディレクティブは、Objective-Cコードでその場でミューテックスロックを作成するための便利な方法です。

この@synchronizedディレクティブは、他のミューテックスロックが行うことを実行します。つまり、異なるスレッドが同じロックを同時に取得するのを防ぎます。

構文:

 @synchronized(key) 
 { 
  // thread-safe code 
 }

例:

 -(void)AppendExisting:(NSString*)val
{
  @synchronized (oldValue) {
      [oldValue stringByAppendingFormat:@"-%@",val];
  }
}

これで、上記のコードは完全にスレッドセーフになりました。複数のスレッドで値を変更できるようになりました。

上記はあいまいな例です...


3
@synchronized(oldValue)であるべきではありませんか?
ジョエル

それとも@synchronized(val, oldValue) { ... }
Valentin Shergin 2014年

「完全にスレッドセーフ」なスキームを見たことがあるかどうかはわかりません。少なくとも、どこかからコードを盲目的にコピーするだけでなく、自分が何をしているのかを知る必要があります。
ホットリック2015年

しかし、上記のコードはまったく何もしないので、結局のところ「完全にスレッドセーフ」だと思います。
ホットリック2015年



-2

@synchronizedあるthread safeメカニズム。この関数内に記述されたコードの一部はcritical section、の一部になり、一度に1つのスレッドしか実行できません。

@synchronizeロックを暗黙的にNSLock適用しますが、明示的に適用します。

スレッドの安全性を保証するだけであり、それを保証するものではありません。私が言いたいのは、あなたはあなたの車のために専門のドライバーを雇うということです、それでもそれは車が事故に遭遇しないことを保証するものではありません。ただし、確率はわずかなままです。


2
これは絶対に間違っています。dispatch_onceは@syncrhonizedと同じことをしません、それはシングルトンの割り当ての下でのみ代用することができます。
jugutier 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.