Apa yang dilakukan @synchronized () sebagai metode tunggal di tujuan C?

88

Saya baru saja membuat metode tunggal, dan saya ingin tahu apa fungsinya @synchronized(), karena saya sering menggunakannya, tetapi tidak tahu artinya.

max_
sumber

Jawaban:

119

Ini mendeklarasikan bagian kritis di sekitar blok kode. Dalam kode multithread, @synchronizedmenjamin bahwa hanya satu utas yang dapat mengeksekusi kode itu di blok pada waktu tertentu.

Jika Anda tidak mengetahui fungsinya, maka aplikasi Anda mungkin tidak multithread, dan Anda mungkin tidak perlu menggunakannya (terutama jika singleton itu sendiri tidak aman untuk thread).


Edit: Menambahkan beberapa informasi lagi yang tidak ada dalam jawaban asli dari tahun 2011.

The @synchronizeddirektif mencegah beberapa thread memasuki setiap wilayah kode yang dilindungi oleh @synchronizeddirektif mengacu pada objek yang sama . Objek yang diteruskan ke @synchronizeddirektif adalah objek yang digunakan sebagai "kunci". Dua utas dapat berada di wilayah kode terlindung yang sama jika objek yang berbeda digunakan sebagai kunci, dan Anda juga dapat menjaga dua wilayah kode yang sama sekali berbeda menggunakan objek yang sama sebagai kunci.

Juga, jika Anda kebetulan lewat nilsebagai objek kunci, tidak ada kunci yang akan diambil sama sekali.

John Calsbeek
sumber
14
Beberapa poin penting: 1) Jika Anda menggunakan pointer nil di @synchronizeddalamnya tidak melakukan apa-apa - Anda tidak terlindungi. 2) @synchronizedadalah lambat .
Hot Licks
Jawaban ini menyesatkan, dan seharusnya bukan jawaban yang diterima. Meskipun apa yang dikatakannya terkadang benar (selama token yang diteruskan ke yang disinkronkan adalah objek yang sama di semua utas), ini tidak lengkap yang menyesatkan. disinkronkan mencegah sejumlah bagian kode terkait untuk dijalankan pada saat yang sama, tidak hanya "kode itu di blok". Parameter yang akan disinkronkan secara efektif menentukan bagian kode mana (atau "blok" saat jawaban memanggilnya) yang dilindungi dari akses bersamaan.
Arda
@Arda Anda benar sekali. Saya telah menambahkan lebih banyak informasi dan tautan ke beberapa dokumentasi Apple tentang @synchronized.
John Calsbeek
@JohnCalsbeek, jawabannya terlihat jauh lebih baik sekarang. Jempol dari saya.
Arda
@HotLicks menarik untuk menunjukkan hal ini, tetapi akan lebih baik untuk mengatakan secara singkat apa yang bisa menjadi alternatif (tautan?)
itMaxence
43

Dari dokumentasi Apple di sini dan di sini :

Direktif @synchronized adalah cara mudah untuk membuat kunci mutex dengan cepat dalam kode Objective-C. Direktif @synchronized melakukan apa yang akan dilakukan kunci mutex lainnya — ini mencegah utas yang berbeda memperoleh kunci yang sama pada waktu yang sama.

Dokumentasi memberikan banyak informasi tentang hal ini. Ada baiknya meluangkan waktu untuk membacanya, terutama mengingat Anda telah menggunakannya tanpa mengetahui apa fungsinya.

csano.dll
sumber
27

The @synchronizeddirektif adalah cara yang nyaman untuk membuat kunci mutex dengan cepat di Objective-C code.

The @synchronizeddirektif melakukan apa saja kunci mutex lain yang akan dilakukan-mencegah benang yang berbeda dari memperoleh kunci yang sama pada waktu yang sama.

Sintaksis:

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

Contoh:

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

Sekarang kode di atas benar-benar aman untuk utas .. Sekarang Beberapa utas dapat mengubah nilainya.

Di atas hanyalah contoh yang tidak jelas ...

Durai Amuthan.H
sumber
3
Bukankah seharusnya @synchronized (oldValue)?
Joel
Atau bahkan @synchronized(val, oldValue) { ... }?
Valentin Shergin
Saya tidak yakin saya pernah melihat skema yang "sangat aman untuk benang". Setidaknya Anda perlu tahu apa yang Anda lakukan dan tidak hanya menyalin kode secara membabi buta dari suatu tempat.
Hot Licks
Tapi saya kira kode di atas adalah "thread safe", karena tidak ada artinya sama sekali.
Hot Licks
6

@ blok tersinkronisasi secara otomatis menangani penguncian dan pembukaan kunci untuk Anda . @sinkronisasi Anda memiliki kunci implisit yang dikaitkan dengan objek yang Anda gunakan untuk menyinkronkan. Berikut adalah diskusi yang sangat informatif tentang topik ini, silakan ikuti Bagaimana cara @synchronized mengunci / membuka kunci di Objective-C?

abdus.me
sumber
-2

@synchronizedadalah thread safemekanisme. Sepotong kode yang tertulis di dalam fungsi ini menjadi bagian critical sectiondarinya, yang hanya dapat dieksekusi oleh satu utas dalam satu waktu.

@synchronizemenerapkan kunci secara implisit sedangkan NSLockmenerapkannya secara eksplisit.

Ini hanya menjamin keamanan benang, bukan menjamin itu. Yang saya maksud adalah Anda menyewa seorang pengemudi ahli untuk mobil Anda, tetap saja itu tidak menjamin mobil tidak akan mengalami kecelakaan. Namun probabilitas tetap kecil.


sumber
2
Ini sangat salah. dispatch_once TIDAK melakukan hal yang sama seperti @syncrhonized, ini HANYA dapat menjadi pengganti di bawah alokasi singleton.
jugutier