Apa yang dimaksud dengan 'disinkronkan'?

994

Saya memiliki beberapa pertanyaan tentang penggunaan dan pentingnya synchronizedkata kunci.

  • Apa arti penting dari synchronizedkata kunci?
  • Kapan metode seharusnya synchronized?
  • Apa artinya secara terprogram dan logis?
Johanna
sumber
1
diskusi bermanfaat antara hashmap dan hashtable, dan sinkronisasi: stackoverflow.com/questions/40471/java-hashmap-vs-hashtable
limc
2
Kemungkinan rangkap dari Bagaimana cara kerja sinkronisasi di Jawa
Marian Paździoch
1
Saya membaca seluruh tautan dokumentasi dari komentar pertama, dan tidak mengerti sampai saya sampai pada paragraf terakhir. Alih-alih menempelkan tautan dan tidak mengutip apa pun, mungkin menyisipkan tautan dan menambahkan kutipan lebih bermanfaat.
Rakib

Jawaban:

878

Kata synchronizedkunci adalah semua tentang utas yang berbeda membaca dan menulis ke variabel, objek dan sumber daya yang sama. Ini bukan topik sepele di Jawa, tapi di sini ada kutipan dari Sun:

synchronized metode memungkinkan strategi sederhana untuk mencegah interferensi utas dan kesalahan konsistensi memori: jika suatu objek terlihat lebih dari satu utas, semua membaca atau menulis ke variabel objek itu dilakukan melalui metode yang disinkronkan.

Singkatnya, ketika Anda memiliki dua utas yang membaca dan menulis ke 'sumber' yang sama, ucapkan variabel bernama foo, Anda perlu memastikan bahwa utas ini mengakses variabel dengan cara atom. Tanpa synchronizedkata kunci, utas 1 Anda mungkin tidak melihat utas perubahan 2 dibuatfoo , atau lebih buruk, itu hanya mungkin setengah diubah. Ini tidak akan seperti yang Anda harapkan secara logis.

Sekali lagi, ini adalah topik non-sepele di Jawa. Untuk mempelajari lebih lanjut, jelajahi topik di sini di SO dan Jalinan tentang:

Terus jelajahi topik ini sampai nama "Brian Goetz" secara permanen dikaitkan dengan istilah "konkurensi" di otak Anda.

Stu Thompson
sumber
71
Jadi, pada dasarnya kata kunci yang disinkronkan ini membuat metode Anda aman?
Rigo Vides
82
Kata kunci yang disinkronkan adalah salah satu alat yang membuat utas kode Anda aman. Hanya menggunakan disinkronkan pada suatu metode atau variabel itu sendiri mungkin atau mungkin tidak melakukan trik. Memiliki pemahaman dasar tentang Java Memory Model sangat penting untuk mendapatkan konkurensi yang benar.
Stu Thompson
28
Kecuali Anda adalah Brian Goetz (atau mungkin Jon Skeet), hampir tidak mungkin untuk membuat konkurensi Java dengan benar hanya dengan bahasa primitif (disinkronkan, mudah berubah). Sebagai permulaan, gunakan paket java.util.concurrent dan bangun di atasnya.
Thilo
12
Lebih jelasnya: metode yang disinkronkan tidak dapat dipanggil secara bersamaan dari banyak utas.
peterh
2
@ Peterh disinkronkan melakukan lebih dari itu, maka penjelasan yang lebih jelas
Stu Thompson
294

Yah, saya pikir kita sudah punya cukup penjelasan teoretis, jadi pertimbangkan kode ini

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n");
    }
}

public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run() {
        theDemo.test(name);
    }
}

public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0;i<10;i++) {
            SOP.print(name + " :: "+i);
            try{
                Thread.sleep(500);
            } catch (Exception e) {
                SOP.print(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo);
    }
}

Catatan: synchronizedmemblokir panggilan utas berikutnya ke metode pengujian () selama eksekusi utas sebelumnya tidak selesai. Utas dapat mengakses metode ini satu per satu. Tanpasynchronized semua utas dapat mengakses metode ini secara bersamaan.

Ketika sebuah thread memanggil metode yang disinkronkan 'tes' dari objek (di sini objek adalah turunan dari kelas 'TheDemo') ia mendapatkan kunci dari objek itu, setiap utas baru tidak dapat memanggil SETIAP metode yang disinkronkan dari objek yang sama selama utas sebelumnya yang telah memperoleh kunci tidak melepaskan kunci.

Hal serupa terjadi ketika metode sinkronisasi kelas statis dipanggil. Utas mendapatkan kunci yang terkait dengan kelas (dalam hal ini metode disinkronkan non statis dari instance kelas itu dapat dipanggil oleh utas apa pun karena kunci tingkat objek masih tersedia). Utas lain tidak akan dapat memanggil metode sinkronisasi statis apa pun dari kelas selama kunci tingkat kelas tidak dilepaskan oleh utas yang saat ini memegang kunci.

Output dengan disinkronkan

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9

Output tanpa disinkronkan

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
Dheeraj Sachan
sumber
7
Contoh yang bagus, baik untuk mengetahui teori, tetapi kode selalu lebih spesifik dan lengkap.
Santi Iglesias
2
@SantiIglesias "Lengkap"? Nggak. Contoh ini menunjukkan perilaku penguncian synchronized, tetapi konsistensi memori diabaikan.
Stu Thompson
2
Konsistensi memori @Stu Thompson adalah hasil dari penguncian
Dheeraj Sachan
@DheerajSachan Dengan logika itu kemudian menggunakan ReentrantLock akan menghasilkan konsistensi memori. Tidak.
Stu Thompson
3
@boltup_im_coding: Metode start () menempatkan Thread dalam keadaan "RUNNABLE", artinya siap untuk dieksekusi atau sudah dieksekusi. Mungkin terjadi bahwa utas lain (biasanya tetapi tidak selalu dengan prioritas lebih tinggi) di status Runnable melompati antrian dan mulai menjalankan. Pada contoh di atas, THREAD 3 kebetulan mendapatkan CPU sebelum THREAD 2.
Sahil J
116

Kata synchronizedkunci mencegah akses bersamaan ke blok kode atau objek dengan beberapa utas. Semua metode Hashtableadalah synchronized, jadi hanya satu utas yang dapat menjalankan salah satu dari mereka sekaligus.

Saat menggunakan non- synchronizedkonstruk like HashMap, Anda harus membangun fitur keamanan-ulir dalam kode Anda untuk mencegah kesalahan konsistensi.

jmort253
sumber
81

synchronizedberarti bahwa dalam lingkungan multi-ulir, objek yang memiliki synchronizedmetode / blok tidak memungkinkan dua utas untuk mengakses synchronizedmetode / blok kode pada saat yang sama. Ini berarti bahwa satu utas tidak dapat membaca sementara utas lainnya memperbaruinya.

Utas kedua sebagai gantinya akan menunggu sampai utas pertama menyelesaikan eksekusi. Overhead adalah kecepatan, tetapi keuntungannya dijamin konsistensi data.

Jika aplikasi Anda menggunakan satu utas, synchronizedblok tidak memberikan manfaat.

Codemwnci
sumber
54

Kata synchronizedkunci menyebabkan utas untuk mendapatkan kunci ketika memasukkan metode, sehingga hanya satu utas yang dapat menjalankan metode pada saat yang sama (untuk contoh objek yang diberikan, kecuali itu adalah metode statis).

Ini sering disebut membuat class-safe, tetapi saya akan mengatakan ini adalah eufemisme. Memang benar bahwa sinkronisasi melindungi keadaan internal vektor agar tidak rusak, ini biasanya tidak banyak membantu pengguna vektor.

Pertimbangkan ini:

 if (vector.isEmpty()){
     vector.add(data);
 }

Meskipun metode yang terlibat disinkronkan, karena mereka sedang dikunci dan dibuka secara terpisah, dua untaian yang sayangnya waktunya dapat membuat vektor dengan dua elemen.

Jadi sebenarnya, Anda harus menyinkronkan dalam kode aplikasi Anda juga.

Karena sinkronisasi tingkat metode adalah a) mahal ketika Anda tidak membutuhkannya dan b) tidak cukup ketika Anda membutuhkan sinkronisasi, sekarang ada penggantian yang tidak disinkronkan (ArrayList dalam kasus Vektor).

Baru-baru ini, paket konkurensi telah dirilis, dengan sejumlah utilitas pintar yang menangani masalah multi-threading.

Thilo
sumber
27

Gambaran

Kata kunci yang disinkronkan di Jawa berkaitan dengan keamanan utas, yaitu ketika beberapa utas membaca atau menulis variabel yang sama.
Ini dapat terjadi secara langsung (dengan mengakses variabel yang sama) atau tidak langsung (dengan menggunakan kelas yang menggunakan kelas lain yang mengakses variabel yang sama).

Kata kunci yang disinkronkan digunakan untuk menentukan blok kode di mana banyak utas dapat mengakses variabel yang sama dengan cara yang aman.

Lebih dalam

Sintaks synchronizedkata kunci mengambil Objectparameter seperti itu (disebut objek kunci ), yang kemudian diikuti oleh a { block of code }.

  • Ketika eksekusi menemukan kata kunci ini, utas saat ini mencoba untuk "mengunci / memperoleh / memiliki" (pilih) objek kunci dan jalankan blok kode yang terkait setelah kunci diperoleh.

  • Setiap penulisan ke variabel di dalam blok kode yang disinkronkan dijamin akan terlihat oleh setiap utas lain yang juga mengeksekusi kode di dalam blok kode yang disinkronkan menggunakan objek kunci yang sama .

  • Hanya satu utas pada satu waktu yang dapat menahan kunci, selama itu semua utas lainnya yang mencoba mendapatkan objek kunci yang sama akan menunggu (jeda eksekusi mereka). Kunci akan dilepaskan ketika eksekusi keluar dari blok kode yang disinkronkan.

Metode yang disinkronkan:

Menambahkan synchronizedkata kunci ke definisi metode sama dengan seluruh badan metode yang dibungkus dengan blok kode yang disinkronkan dengan objek kunci menjadi this (misalnya metode) dan ClassInQuestion.getClass() (untuk metode kelas) .

- Metode Instance adalah metode yang tidak memiliki statickata kunci.
- Metode kelas adalah metode yang memiliki statickata kunci.

Teknis

Tanpa sinkronisasi, itu tidak dijamin di mana urutan membaca dan menulis terjadi, mungkin meninggalkan variabel dengan sampah.
(Misalnya variabel bisa berakhir dengan setengah dari bit yang ditulis oleh satu utas dan setengah dari bit yang ditulis oleh utas lain, meninggalkan variabel dalam keadaan yang tak satu pun dari utas mencoba untuk menulis, tetapi kekacauan gabungan keduanya.)

Tidak cukup untuk menyelesaikan operasi penulisan di utas sebelumnya (waktu di dinding) utas lain membacanya, karena perangkat keras bisa saja menembolok nilai variabel, dan utas bacaan akan melihat nilai yang di-cache bukan apa yang dituliskan ke Itu.

Kesimpulan

Jadi dalam kasus Java, Anda harus mengikuti Java Memory Model untuk memastikan bahwa kesalahan threading tidak terjadi.
Dengan kata lain: Gunakan sinkronisasi, operasi atom atau kelas yang menggunakannya untuk Anda di bawah tenda.

Sumber

http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Spesifikasi Bahasa Java®, 2015-02-13

Gima
sumber
Maaf, tapi saya punya contoh ini dan saya tidak mengerti artinya: `Integer i1 = Arrays.asList (1,2,3,4,5) .stream (). FindAny (). Get (); disinkronkan (i1) {Integer i2 = Arrays.asList (6,7,8,9,10) .parallelStream () .orted () .findAny (). get (); System.out.println (i1 + "" + i2); } `1. Mengapa Anda mengaktifkan blok pada instance pertama dan doa ini tidak berpengaruh pada kode? 2. Contoh kedua akan aman-thread, meskipun doa pada blok pertama?
Adryr83
1
@ Adryr83 Jika Anda memiliki pertanyaan, Anda mungkin bisa menanyakannya dengan memposting pertanyaan baru. Tapi karena kita ada di sini, saya akan menguraikan apa yang saya bisa (pertanyaan Anda agak sulit dimengerti). Dari apa yang saya tahu tentang potongan kode itu, sepertinya tidak mengandung apa pun yang membutuhkan sinkronisasi. Itu di luar konteks. Saran: Jika Anda bisa, coba bagi kode menjadi beberapa bagian yang lebih kecil, dan kemudian cari jawaban tentang itu. Jauh lebih mudah untuk mencoba memahami masalah kecil dan terisolasi, daripada mencoba mencari satu blok kode besar.
Gima
21

Anggap saja semacam pintu pagar seperti yang mungkin Anda temukan di lapangan sepakbola. Ada steam paralel dari orang yang ingin masuk tetapi di pintu putar mereka 'disinkronkan'. Hanya satu orang pada satu waktu yang bisa melewati. Semua yang ingin melewati akan melakukannya, tetapi mereka mungkin harus menunggu sampai mereka bisa melewatinya.

paul
sumber
16

Apa kata kunci yang disinkronkan?

Utas berkomunikasi terutama dengan berbagi akses ke bidang dan bidang referensi objek merujuk. Bentuk komunikasi ini sangat efisien, tetapi memungkinkan dua jenis kesalahan: interferensi utas dan kesalahan konsistensi memori . Alat yang diperlukan untuk mencegah kesalahan ini adalah sinkronisasi.

Blok atau metode yang disinkronkan mencegah interferensi utas dan memastikan bahwa data konsisten. Kapan saja, hanya satu utas yang dapat mengakses blok atau metode yang disinkronkan ( bagian kritis ) dengan memperoleh kunci. Utas lainnya akan menunggu pelepasan kunci untuk mengakses bagian kritis .

Kapan metode disinkronkan?

Metode disinkronkan ketika Anda menambahkan synchronizeddefinisi atau deklarasi metode. Anda juga dapat menyinkronkan blok kode tertentu dengan-dalam metode.

Apa artinya secara pro gramatikal dan logis?

Ini berarti bahwa hanya satu utas yang dapat mengakses bagian kritis dengan memperoleh kunci. Kecuali jika utas ini melepaskan kunci ini, semua utas lainnya harus menunggu untuk mendapatkan kunci. Mereka tidak memiliki akses untuk masuk ke bagian kritis tanpa mendapatkan kunci.

Ini tidak bisa dilakukan dengan sihir. Merupakan tanggung jawab programmer untuk mengidentifikasi bagian-bagian penting dalam aplikasi dan menjaganya sesuai. Java menyediakan kerangka kerja untuk menjaga aplikasi Anda, tetapi di mana dan apa semua bagian yang harus dijaga adalah tanggung jawab programmer.

Lebih detail dari halaman dokumentasi java

Kunci dan Sinkronisasi Intrinsik:

Sinkronisasi dibangun di sekitar entitas internal yang dikenal sebagai kunci intrinsik atau kunci monitor. Kunci intrinsik berperan dalam kedua aspek sinkronisasi: menegakkan akses eksklusif ke keadaan objek dan membangun hubungan sebelum terjadi yang penting untuk visibilitas.

Setiap objek memiliki kunci intrinsik yang terkait dengannya . Dengan konvensi, utas yang memerlukan akses eksklusif dan konsisten ke bidang objek harus memperoleh kunci intrinsik objek sebelum mengaksesnya, dan kemudian melepaskan kunci intrinsik ketika dilakukan dengan mereka.

Sebuah thread dikatakan memiliki kunci intrinsik antara waktu kunci tersebut diperoleh dan melepaskan kunci tersebut. Selama utas memiliki kunci intrinsik, tidak ada utas lain yang bisa mendapatkan kunci yang sama. Utas lainnya akan memblokir ketika mencoba untuk mendapatkan kunci.

Ketika utas melepaskan kunci intrinsik, hubungan yang terjadi sebelum terjadi antara tindakan itu dan akuisisi berikutnya dari kunci yang sama.

Membuat metode yang disinkronkan memiliki dua efek :

Pertama, tidak mungkin untuk dua doa metode disinkronkan pada objek yang sama untuk interleave.

Ketika satu utas menjalankan metode yang disinkronkan untuk suatu objek, semua utas lainnya yang menjalankan metode yang disinkronkan untuk blok objek yang sama (menunda eksekusi) hingga utas pertama selesai dengan objek tersebut.

Kedua, ketika metode yang disinkronkan keluar, itu secara otomatis membangun hubungan yang terjadi sebelum dengan setiap doa berikutnya dari metode yang disinkronkan untuk objek yang sama.

Ini menjamin bahwa perubahan keadaan objek terlihat oleh semua utas.

Cari alternatif lain untuk sinkronisasi di:

Hindari disinkronkan (ini) di Jawa?

Ravindra babu
sumber
11

Synchronized normal methodsetara dengan Synchronized statement(gunakan ini)

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

Synchronized static methodsetara dengan Synchronized statement(gunakan kelas)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

Pernyataan tersinkronisasi (menggunakan variabel)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

Karena synchronized, kami memiliki keduanya Synchronized Methodsdan Synchronized Statements. Namun, Synchronized Methodsmirip dengan itu Synchronized Statementsjadi kita hanya perlu mengerti Synchronized Statements.

=> Pada dasarnya, kita akan memilikinya

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

Berikut adalah 2 pemikiran yang membantu pemahaman synchronized

  • Setiap objek / kelas memiliki intrinsic lockketerkaitan dengannya.
  • Ketika thread memanggil sebuah synchronized statement, secara otomatis memperoleh intrinsic lockuntuk itu synchronized statement'sobjek dan rilis ketika metode kembali. Selama utas memiliki intrinsic lock, TIDAK ada utas lain yang dapat memperoleh kunci SAMA => aman.

=> Ketika thread Amemanggil synchronized(this){// code 1}=> semua kode blok (kelas dalam) di mana memiliki synchronized(this)dan semua synchronized normal method(kelas dalam) dikunci karena kunci SAMA . Ini akan dieksekusi setelah thread Amembuka kunci ("// kode 1" selesai).

Perilaku ini mirip dengan synchronized(a variable){// code 1}atau synchronized(class).

SAMA KUNCI => kunci (tidak bergantung pada metode mana? Atau pernyataan mana?)

Gunakan metode yang disinkronkan atau pernyataan yang disinkronkan?

Saya lebih suka synchronized statementskarena lebih bisa diperpanjang. Contoh, di masa depan, Anda hanya perlu menyinkronkan bagian dari metode. Contoh, Anda memiliki 2 metode yang disinkronkan dan tidak memiliki yang relevan satu sama lain, namun ketika sebuah thread menjalankan metode, itu akan memblokir metode lain (itu dapat mencegah dengan menggunakan synchronized(a variable)).

Namun, menerapkan metode yang disinkronkan adalah sederhana dan kode terlihat sederhana. Untuk beberapa kelas, hanya ada 1 metode yang disinkronkan, atau semua metode yang disinkronkan di kelas yang relevan satu sama lain => kita dapat menggunakan synchronized methoduntuk membuat kode lebih pendek dan mudah dimengerti

Catatan

(itu tidak relevan dengan banyak synchronizedhal, itu adalah perbedaan antara objek dan kelas atau tidak ada yang statis dan statis).

  • Ketika Anda menggunakan synchronizedatau metode normal atau synchronized(this)atausynchronized(non-static variable) akan disinkronkan berdasarkan pada setiap instance objek.
  • Ketika Anda menggunakan synchronizedatau metode statis synchronized(class)atau synchronized(static variable)akan disinkronkan berdasarkan kelas

Referensi

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Semoga ini bisa membantu

Phan Van Linh
sumber
11

Berikut ini penjelasan dari The Java Tutorials .

Pertimbangkan kode berikut:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

jika countmerupakan instance dari SynchronizedCounter, maka membuat metode ini disinkronkan memiliki dua efek:

  • Pertama, tidak mungkin untuk dua doa metode disinkronkan pada objek yang sama untuk interleave. Ketika satu utas menjalankan metode yang disinkronkan untuk suatu objek, semua utas lainnya yang menjalankan metode yang disinkronkan untuk blok objek yang sama (menunda eksekusi) hingga utas pertama selesai dengan objek tersebut.
  • Kedua, ketika metode yang disinkronkan keluar, itu secara otomatis membangun hubungan yang terjadi sebelum dengan setiap doa berikutnya dari metode yang disinkronkan untuk objek yang sama. Ini menjamin bahwa perubahan keadaan objek terlihat oleh semua utas.
Shahryar Saljoughi
sumber
9

Untuk pemahaman saya disinkronkan pada dasarnya berarti bahwa kompiler menulis monitor.enter dan monitor.exit di sekitar metode Anda. Karena itu mungkin thread aman tergantung pada bagaimana digunakan (maksud saya adalah Anda dapat menulis objek dengan metode yang disinkronkan bukan threadsafe tergantung pada apa yang kelas Anda lakukan).

Tempat menyimpan bahan makanan
sumber
5

Apa yang tidak ada jawaban lain adalah salah satu aspek penting: hambatan memori . Sinkronisasi utas pada dasarnya terdiri dari dua bagian: serialisasi dan visibilitas. Saya menyarankan semua orang ke google untuk "jvm memory barrier", karena ini adalah topik yang tidak sepele dan sangat penting (jika Anda memodifikasi data bersama yang diakses oleh banyak utas). Setelah melakukan itu, saya menyarankan melihat kelas paket java.util.concurrent yang membantu untuk menghindari menggunakan sinkronisasi eksplisit, yang pada gilirannya membantu menjaga program sederhana dan efisien, bahkan mungkin mencegah kebuntuan.

Salah satu contohnya adalah ConcurrentLinkedDeque . Bersama dengan pola perintah, ini memungkinkan untuk membuat utas pekerja yang sangat efisien dengan memasukkan perintah ke dalam antrian bersamaan - tidak diperlukan sinkronisasi eksplisit, tidak ada deadlock yang mungkin, tidak ada sleep eksplisit () diperlukan, cukup polling antrian dengan memanggil take ().

Singkatnya: "sinkronisasi memori" terjadi secara implisit ketika Anda memulai utas, utas berakhir, Anda membaca variabel volatil, Anda membuka kunci monitor (meninggalkan blok / fungsi yang disinkronkan) dll. "Sinkronisasi" ini mempengaruhi (dalam arti "siram" ") semua penulisan dilakukan sebelum tindakan tertentu. Dalam kasus ConcurrentLinkedDeque yang disebutkan di atas , dokumentasi "mengatakan":

Efek konsistensi memori: Seperti halnya kumpulan konkuren lainnya, tindakan dalam utas sebelum menempatkan objek ke dalam ConcurrentLinkedDeque terjadi sebelum tindakan setelah akses atau penghapusan elemen itu dari ConcurrentLinkedDeque di utas lain.

Perilaku implisit ini adalah aspek yang agak merusak karena kebanyakan programmer Java tanpa banyak pengalaman hanya akan mengambil banyak seperti yang diberikan karena itu. Dan kemudian tiba-tiba tersandung thread ini setelah Jawa tidak melakukan apa yang "seharusnya" dilakukan dalam produksi di mana ada beban kerja yang berbeda - dan itu cukup sulit untuk menguji masalah konkurensi.

pengguna1050755
sumber
3

Disinkronkan secara sederhana berarti bahwa beberapa utas jika dikaitkan dengan objek tunggal dapat mencegah baca dan tulis kotor jika blok yang disinkronkan digunakan pada objek tertentu. Untuk memberi Anda lebih banyak kejelasan, mari kita ambil contoh:

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

Kami telah membuat dua objek kelas MyRunnable, runnable1 dibagikan dengan utas 1 dan utas 3 & runnable2 dibagikan hanya dengan utas 2. Sekarang ketika t1 dan t3 dimulai tanpa disinkronkan sedang digunakan, output PFB yang menunjukkan bahwa kedua thread 1 dan 3 secara bersamaan mempengaruhi nilai var di mana untuk thread 2, var memiliki memori sendiri.

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

Menggunakan Sinkronisasi, utas 3 menunggu utas 1 selesai di semua skenario. Ada dua kunci yang diperoleh, satu di runnable1 dibagikan dengan utas 1 dan utas 3 dan lainnya pada runnable2 hanya dibagikan oleh utas 2.

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18
paras4all
sumber
Sinkronisasi berarti lebih dari itu: ia memiliki dampak mendalam pada penghalang memori.
user1050755
1

disinkronkan sederhana berarti tidak ada dua utas yang dapat mengakses blok / metode secara bersamaan. Ketika kita mengatakan blok / metode kelas mana pun disinkronkan itu berarti hanya satu utas yang dapat mengaksesnya sekaligus. Secara internal utas yang mencoba mengaksesnya pertama-tama mengambil kunci pada objek itu dan selama kunci ini tidak tersedia, tidak ada utas lain yang dapat mengakses metode / blok yang disinkronkan dari instance kelas tersebut.

Catatan utas lainnya dapat mengakses metode objek yang sama yang tidak ditentukan untuk disinkronkan. Utas dapat melepaskan kunci dengan menelepon

Object.wait()
Aniket Thakur
sumber
0

synchronizedblock in Java adalah monitor dalam multithreading. synchronizedblok dengan objek / kelas yang sama dapat dieksekusi oleh hanya satu utas, semua yang lain sedang menunggu. Ini dapat membantu race conditionsituasi ketika beberapa utas mencoba memperbarui variabel yang sama (langkah pertama menggunakan volatileTentang )

Java 5diperpanjang synchronizeddengan mendukung happens-before[Tentang]

Buka kunci (blok tersinkronisasi atau metode keluar) dari monitor terjadi sebelum setiap kunci berikutnya (blok disinkronkan atau entri metode) dari monitor yang sama.

Langkah selanjutnya adalah java.util.concurrent

volatile vs disinkronkan

yoAlex5
sumber
-6

disinkronkan adalah kata kunci di Jawa yang digunakan untuk membuat hubungan sebelum terjadi di lingkungan multithreading untuk menghindari inkonsistensi memori dan kesalahan interferensi thread.

Sharad
sumber