JavaRush /Java Blog /Random-ID /Level 26. Jawaban pertanyaan wawancara pada topik level. ...
zor07
Level 31
Санкт-Петербург

Level 26. Jawaban pertanyaan wawancara pada topik level. Bagian 2. Soal 6-9, 11-12

Dipublikasikan di grup Random-ID
Level 26. Jawaban pertanyaan wawancara pada topik level.  Bagian 2. Soal 6-9, 11-12 - 1

6. Apa itu Cancarenzi?

Konkurensi adalah perpustakaan kelas di Java yang berisi kelas khusus yang dioptimalkan untuk bekerja di banyak thread. Kelas-kelas ini dikumpulkan dalam satu paket java.util.concurrent. Mereka dapat dibagi secara skematis menurut fungsinya sebagai berikut: Level 26. Jawaban pertanyaan wawancara pada topik level.  Bagian 2. Soal 6-9, 11-12 - 2Koleksi Bersamaan - sekumpulan koleksi yang bekerja lebih efisien dalam lingkungan multi-utas daripada koleksi universal standar dari java.utilsebuah paket. Alih-alih pembungkus dasar Collections.synchronizedListdengan memblokir akses ke seluruh koleksi, kunci pada segmen data digunakan, atau pekerjaan dioptimalkan untuk pembacaan data paralel menggunakan algoritma bebas tunggu. Antrian - antrian non-pemblokiran dan pemblokiran dengan dukungan multi-threading. Antrian non-pemblokiran dirancang untuk kecepatan dan pengoperasian tanpa memblokir thread. Pemblokiran antrian digunakan ketika Anda perlu "memperlambat" thread "Produser" atau "Konsumen" jika beberapa kondisi tidak terpenuhi, misalnya antrian kosong atau meluap, atau tidak ada "Konsumen" bebas. Sinkronisasi adalah utilitas tambahan untuk menyinkronkan thread. Mereka adalah senjata ampuh dalam komputasi “paralel”. Pelaksana - berisi kerangka kerja yang sangat baik untuk membuat kumpulan thread, menjadwalkan tugas asinkron, dan mendapatkan hasil. Kunci - mewakili mekanisme sinkronisasi thread alternatif dan lebih fleksibel dibandingkan dengan synchronizedmekanisme waitdasar notify. Atomics - kelas dengan dukungan untuk operasi atom pada primitif dan referensi. Sumber:notifyAll

7. Kelas Kankarensi apa yang kamu ketahui?

Jawaban atas pertanyaan ini dinyatakan dengan sempurna dalam artikel ini . Saya tidak melihat ada gunanya mencetak ulang semuanya di sini, jadi saya hanya akan memberikan deskripsi tentang kelas-kelas yang saya mendapat kehormatan untuk membiasakan diri secara singkat. ConcurrentHashMap<K, V> - Tidak seperti Hashtabledan memblokir synhronized, HashMapdata disajikan dalam bentuk segmen, dibagi menjadi hash kunci. Akibatnya, data diakses berdasarkan segmen, bukan berdasarkan objek tunggal. Selain itu, iterator mewakili data untuk jangka waktu tertentu dan tidak membuang ConcurrentModificationException. AtomicBoolean, AtomicInteger, AtomicLong, AtomicIntegerArray, AtomicLongArray - Bagaimana jika di kelas Anda perlu menyinkronkan akses ke satu variabel sederhana bertipe int? Anda dapat menggunakan konstruksi dengan synchronized, dan saat menggunakan operasi atom set/get, volatile. Namun Anda dapat melakukannya lebih baik lagi dengan menggunakan kelas baru Atomic*. Karena penggunaan CAS, operasi dengan kelas-kelas ini lebih cepat dibandingkan jika disinkronkan melalui synchronized/volatile. Ditambah lagi, ada metode penambahan atom dengan jumlah tertentu, serta kenaikan/pengurangan.

8. Bagaimana cara kerja kelas ConcurrentHashMap?

Pada saat diperkenalkan, ConcurrentHashMappengembang Java memerlukan implementasi peta hash berikut:
  • Keamanan benang
  • Tidak ada kunci di seluruh tabel saat mengaksesnya
  • Sebaiknya tidak ada kunci meja saat melakukan operasi membaca
Ide implementasi utama ConcurrentHashMapadalah sebagai berikut:
  1. Elemen peta

    Berbeda dengan elemen HashMap, Entryin ConcurrentHashMapdideklarasikan sebagai volatile. Ini adalah fitur penting, juga karena adanya perubahan pada JMM .

    static final class HashEntry<K, V> {
        final K key;
        final int hash;
        volatile V value;
        final HashEntry<K, V> next;
    
        HashEntry(K key, int hash, HashEntry<K, V> next, V value) {
            this .key = key;
            this .hash = hash;
            this .next = next;
            this .value = value;
         }
    
        @SuppressWarnings("unchecked")
        static final <K, V> HashEntry<K, V>[] newArray(int i) {
            return new HashEntry[i];
        }
    }
  2. Fungsi hash

    ConcurrentHashMapfungsi hashing yang ditingkatkan juga digunakan.

    Izinkan saya mengingatkan Anda seperti apa di HashMapJDK 1.2:

    static int hash(int h) {
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

    Versi dari ConcurrentHashMap JDK 1.5:

    private static int hash(int h) {
        h += (h << 15) ^ 0xffffcd7d;
        h ^= (h >>> 10);
        h += (h << 3);
        h ^= (h >>> 6);
        h += (h << 2) + (h << 14);
        return h ^ (h >>> 16);
    }

    Mengapa fungsi hash perlu dibuat lebih kompleks? Tabel dalam peta hash memiliki panjang yang ditentukan oleh pangkat dua. Untuk kode hash yang representasi binernya tidak berbeda pada posisi rendah dan tinggi, kita akan mengalami tabrakan. Meningkatkan kompleksitas fungsi hash hanya menyelesaikan masalah ini, mengurangi kemungkinan tabrakan di peta.

  3. Segmen

    Peta dibagi menjadi N segmen berbeda (16 secara default, nilai maksimumnya bisa 16 bit dan merupakan pangkat dua). Setiap segmen adalah tabel elemen peta yang aman untuk thread. Menambah jumlah segmen akan mendorong operasi modifikasi untuk menjangkau beberapa segmen, sehingga mengurangi kemungkinan pemblokiran pada waktu proses.

  4. Tingkat Konkurensi

    Parameter ini mempengaruhi penggunaan kartu memori dan jumlah segmen dalam kartu.

    Jumlah segmen akan dipilih sebagai pangkat dua terdekat yang lebih besar dari tingkat konkurensi. Menurunkan concurrencyLevel membuat thread lebih mungkin memblokir segmen peta saat menulis. Melebih-lebihkan indikator menyebabkan penggunaan memori yang tidak efisien. Jika hanya satu thread yang akan mengubah peta, dan sisanya akan membaca, disarankan untuk menggunakan nilai 1.

  5. Total

    Jadi, keunggulan utama dan fitur implementasi ConcurrentHashMap:

    • hashmapPeta ini memiliki antarmuka interaksi yang mirip dengan
    • Operasi baca tidak memerlukan kunci dan dilakukan secara paralel
    • Operasi tulis seringkali juga dapat dilakukan secara paralel tanpa pemblokiran
    • Saat membuat, yang diperlukan ditunjukkan concurrencyLevel, ditentukan dengan membaca dan menulis statistik
    • Elemen peta memiliki nilai valueyang dinyatakan sebagaivolatile
    Sumber: Cara Kerja ConcurrentHashMap

9. Apa yang dimaksud dengan kelas Kunci?

Untuk mengontrol akses ke sumber daya bersama, kita dapat menggunakan kunci sebagai alternatif dari operator yang disinkronkan. Fungsi penguncian dikemas dalam java.util.concurrent.locks. Pertama, thread mencoba mengakses sumber daya bersama. Jika gratis, maka kunci dipasang pada utas. Setelah pekerjaan selesai, kunci pada sumber daya bersama dilepaskan. Jika sumber daya tidak gratis dan kunci telah dipasang padanya, maka thread menunggu hingga kunci ini dilepaskan. Kelas kunci mengimplementasikan antarmuka Lockyang mendefinisikan metode berikut:
  • void lock():menunggu sampai kunci diperoleh
  • boolean tryLock():mencoba mendapatkan kunci; jika kunci diperoleh, ia mengembalikan true . Jika kunci tidak diperoleh, ia mengembalikan false . Berbeda dengan metode ini, lock()metode ini tidak menunggu untuk mendapatkan kunci jika tidak tersedia
  • void unlock():menghilangkan kuncinya
  • Condition newCondition():mengembalikan objek Conditionyang terkait dengan kunci saat ini
Pengorganisasian penguncian dalam kasus umum cukup sederhana: untuk mendapatkan kunci, metode ini disebut lock(), dan setelah selesai bekerja dengan sumber daya bersama, metode ini disebut unlock(), yang melepaskan kunci. Objek ini Conditionmemungkinkan Anda mengelola pemblokiran. Sebagai aturan, untuk bekerja dengan kunci, kelas ReentrantLockdari paket digunakan.Kelas java.util.concurrent.locks.ini mengimplementasikan antarmuka Lock. Mari kita lihat penggunaan Java Lock API menggunakan program kecil sebagai contoh: Jadi, katakanlah kita memiliki kelas Resourcedengan beberapa metode thread-safe dan metode yang tidak memerlukan keamanan thread.
public class Resource {

    public void doSomething(){
        // пусть здесь происходит работа с базой данных
    }

    public void doLogging(){
        // потокобезопасность для логгирования нам не требуется
    }
}
Sekarang mari kita ambil kelas yang mengimplementasikan antarmuka Runnabledan menggunakan metode kelas Resource.
public class SynchronizedLockExample implements Runnable{

    // экземпляр класса Resource для работы с методами
    private Resource resource;

    public SynchronizedLockExample(Resource r){
        this.resource = r;
    }

    @Override
    public void run() {
        synchronized (resource) {
            resource.doSomething();
        }
        resource.doLogging();
    }
}
Sekarang mari kita tulis ulang program di atas menggunakan Lock API, bukan synchronized.
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// класс для работы с Lock API. Переписан с приведенной выше программы,
// но уже без использования ключевого слова synchronized
public class ConcurrencyLockExample implements Runnable{

    private Resource resource;
    private Lock lock;

    public ConcurrencyLockExample(Resource r){
        this.resource = r;
        this.lock = new ReentrantLock();
    }

    @Override
    public void run() {
        try {
            // лочим на 10 секунд
            if(lock.tryLock(10, TimeUnit.SECONDS)){
            resource.doSomething();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            //убираем лок
            lock.unlock();
        }
        // Для логгирования не требуется потокобезопасность
        resource.doLogging();
    }

}
Seperti yang Anda lihat dari programnya, kami menggunakan metode ini tryLock()untuk memastikan bahwa thread hanya menunggu dalam jangka waktu tertentu. Jika tidak mendapatkan kunci pada objek, maka ia akan log dan keluar. Poin penting lainnya. Anda harus menggunakan blok try-finallyuntuk memastikan bahwa kunci akan dilepaskan meskipun metode tersebut doSomething()memunculkan pengecualian. Sumber:

11. Apa itu muteks?

Mutex adalah objek khusus untuk menyinkronkan thread/proses. Ini dapat memerlukan dua keadaan - sibuk dan bebas. Sederhananya, mutex adalah variabel boolean yang mengambil dua nilai: sibuk (benar) dan bebas (salah). Ketika sebuah thread menginginkan kepemilikan eksklusif atas suatu objek, ia menandai mutex-nya sebagai sibuk, dan ketika thread tersebut selesai mengerjakannya, ia menandai mutex-nya sebagai bebas. Mutex dilampirkan ke setiap objek di Java. Hanya mesin Java yang memiliki akses langsung ke mutex. Itu disembunyikan dari programmer.

12. Apa itu monitor?

Monitor adalah mekanisme khusus (sepotong kode) - tambahan pada mutex, yang memastikan pengoperasian yang benar dengannya. Lagi pula, menandai bahwa objek sedang sibuk saja tidak cukup; kita juga harus memastikan bahwa thread lain tidak mencoba menggunakan objek yang sibuk. Di Java, monitor diimplementasikan menggunakan kata kunci synchronized. Saat kita menulis blok tersinkronisasi, kompiler Java menggantinya dengan tiga potong kode:
  1. Di awal blok synchronized, kode ditambahkan yang menandai mutex sebagai sibuk.
  2. Di akhir blok, synchronizedsebuah kode ditambahkan yang menandai mutex sebagai gratis.
  3. Sebelum blok, synchronizedditambahkan kode yang memeriksa apakah mutex sedang sibuk, maka thread harus menunggu hingga dirilis.
Bagian 1
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION