Pengertian java.lang.Thread.State: WAITING (parkir)

91

Pertama, pertanyaan yang sangat bodoh, saya hanya bertanya-tanya apa artinya menunggu 'parkir'? Apakah utas menunggu untuk diparkir atau baru saja diparkir dan oleh karena itu dalam status menunggu? Dan ketika parkir itu terjadi, berapa banyak sumber daya cpu / memori yang diambil? Apa tujuan memarkir utas?

Kedua, dengan melihat metode park pada java thread API

Menonaktifkan utas saat ini untuk tujuan penjadwalan utas kecuali izin tersedia.

Jika izin tersedia maka izin tersebut digunakan dan panggilan langsung kembali; jika tidak, utas saat ini menjadi dinonaktifkan untuk tujuan penjadwalan utas dan tidak aktif hingga salah satu dari tiga hal terjadi .....

Bahasa Inggris bukan bahasa utama saya, jadi saya memiliki beberapa kesulitan untuk memahaminya, saya bermaksud 'izin' sebagai semacam 'izin untuk memarkir utas', jadi pertanyaan yang mengikuti:

  • Apa maksudnya itu, apa itu 'izin', dan siapa serta bagaimana cara pemeriksaan izin tersebut?
  • Apa artinya: 'jika ada izin, maka dikonsumsi', apakah 'diparkir'?
  • berikut, jika poin kedua benar, lalu apa perbedaan antara 'parkir' dan 'tidak aktif'? Jika saya memiliki izin, saya dapat memarkirnya selamanya dan jika tidak, saya dapat membuatnya 'tidak aktif'?

Terima kasih

Leonardo
sumber

Jawaban:

37

Izin adalah izin untuk melanjutkan pelaksanaan. Parkir berarti menangguhkan eksekusi sampai izin tersedia.

Tidak seperti Semaphoreizin, izin LockSupportterkait dengan utas (mis. Izin diberikan ke utas tertentu) dan tidak terakumulasi (yaitu hanya ada satu izin per utas, ketika utas menggunakan izin, izin itu menghilang).

Anda dapat memberikan izin ke utas dengan menelepon unpark(). Sebuah utas dapat menangguhkan eksekusinya hingga izin tersedia (atau utas terputus, atau batas waktu kedaluwarsa, dll) dengan memanggil park(). Jika izin tersedia, thread yang diparkir akan menggunakannya dan keluar dari park()metode.

axtavt
sumber
2
Jadi dengan asumsi kembali, jika utas A memanggil 'parkir' untuk utas B, tetapi izin tersedia, yaitu 'B tidak dapat diparkir', maka panggilan yang dilakukan oleh A hanya kembali dan B tidak diparkir. Jika tidak ada izin yang tersedia, B harus patuh. Lantas, apakah penantian (parkir) itu berarti "A mencoba memarkir saya karena saya tidak punya izin tapi saya tidak bisa melakukannya sekarang jadi saya memblokir A juga"? Maaf untuk kalimat panjang ini. Saya kira penantian ini cukup memakan sumber daya. Saya masih bertanya-tanya siapa yang mengelola semua urusan perizinan. Siapa / apa yang memutuskan bahwa suatu utas memiliki izin, sementara yang lain tidak.
Leonardo
2
@Leonardo: Sebuah utas hanya dapat parkir sendiri, tidak ada cara untuk memarkir utas lainnya. Jadi, menelepon park()berarti "Saya ingin menangguhkan eksekusi saya sampai beberapa thread lain memberi saya izin dengan menelepon unpark()".
axtavt
Jadi sebuah utas tidak dapat memarkir utas lain, tetapi dapat dibatalkan parkirnya oleh utas lain? Apakah itu benar ? Jadi, kapan parkir itu terjadi? Mungkin utas tidak memiliki tugas untuk dilakukan saat ini, dan cara memeriksanya adalah dengan melihat terus-menerus pada izinnya? Ini akan cocok untuk utas daemon misalnya.
Leonardo
Juga, WAITING (parkir) berarti menunggu untuk diparkir, atau dalam keadaan menunggu setelah diparkir? Maaf, saya tahu ini pertanyaan bodoh :-)
Leonardo
3
@Leonardo: Artinya menunggu setelah diparkir.
axtavt
11

Sesuai dengan dokumentasi java Thread State , thread A dapat masuk ke status WAITING karena tiga alasan:

  1. Object.wait tanpa batas waktu
  2. Thread.join tanpa batas waktu
  3. LockSupport.park

Saat Anda memanggil metode park pada Thread, itu menonaktifkan thread untuk tujuan penjadwalan thread kecuali jika izin tersedia. Anda dapat memanggil metode unpark untuk menyediakan izin untuk utas yang diberikan, jika belum tersedia.

Jadi, ketika Thread Anda dalam mode WAITING oleh LockSupport.park, itu akan menampilkan Anda sebagai WAITING (parkir).

Harap perhatikan bahwa, Anda dapat menelepon parkir di Thread saat ini saja. Mekanisme ini sangat membantu untuk mengimplementasikan Pola Desain Produsen-Konsumen.

Badal
sumber
3

Dari deskripsi kelas (di bagian atas javadoc LockSupport ) di mana ia menjelaskan izin:

Asosiasi kelas ini dengan setiap utas yang menggunakannya, izin (dalam arti kelas Semaphore). Panggilan untuk parkir akan segera dikembalikan jika izin tersedia, memakan [izin] dalam prosesnya; jika tidak [panggilan untuk parkir] dapat memblokir. Panggilan untuk membatalkan parkir membuat izin tersedia, jika belum tersedia. (Tidak seperti Semaphores, izin tidak menumpuk. Paling banyak ada satu.)

(Saya memperluas [teks] agar lebih mudah dibaca oleh penutur non-Inggris.)

Semoga seseorang dengan pemahaman yang lebih dalam dapat menguraikan hal ini. Lihat jawaban axtavt.

Sebagai catatan terakhir, kutipan terakhir dari javadoc:

Metode ini dirancang untuk digunakan sebagai alat untuk membuat utilitas sinkronisasi tingkat yang lebih tinggi, dan tidak dengan sendirinya berguna untuk sebagian besar aplikasi kontrol konkurensi.

Charles Goodwin
sumber
3

Bagian yang membuat saya memikirkan kembali pertanyaan ini yang tidak dapat saya singkirkan saat membaca dokumentasi, adalah:

Jika izin tersedia maka izin tersebut digunakan dan panggilan kembali segera ...

Jadi, ketika izin "tersedia", siapa dan bagaimana membuatnya tersedia, sehingga bisa langsung dikonsumsi? Ini entah bagaimana sepele untuk mengetahuinya:

public static void main(String[] args) {

    Thread parkingThread = new Thread(() -> {
        System.out.println("Will go to sleep...");
        sleepTwoSeconds();
        System.out.println("Parking...");
        // this call will return immediately since we have called  LockSupport::unpark
        // before this method is getting called, making the permit available
        LockSupport.park();
        System.out.println("After parking...");
    });

    parkingThread.start();

    // hopefully this 1 second is enough for "parkingThread" to start
    // _before_ we call un-park
    sleepOneSecond();
    System.out.println("Un-parking...");
    // making the permit available while the thread is running and has not yet
    // taken this permit, thus "LockSupport.park" will return immediately
    LockSupport.unpark(parkingThread);

}

private static void sleepTwoSeconds() {
    try {
        Thread.sleep(1000 * 2);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

private static void sleepOneSecond() {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}    

Kode tersebut berbicara sendiri, threadsedang berjalan tetapi belum dipanggil LockSupport.park, sementara beberapa utas lain memanggilnya LockSupport.unpark- sehingga membuat izin tersedia. Setelah itu kami menelepon LockSupport.parkdan itu segera kembali karena izin tersedia.

Setelah Anda memikirkannya, ini agak berbahaya, jika Anda mengekspos utas Anda ke beberapa kode yang tidak Anda kontrol dan kode itu memanggil LockSupport.unparksaat Anda parksetelah itu - itu mungkin tidak berfungsi.

Eugene
sumber
Poin yang sangat bagus, saya akan berpikir bahwa aktivitas pemberian izin - yaitu memanggil unpark () - hanya relevan ketika sebuah thread sedang diparkir.
Alfred Xiao
@AlfredXiao setuju, ini adalah sesuatu yang juga mengejutkan saya, tapi sepertinya masuk akal, saya kira.
Eugene
1

Seperti yang saya pahami, "izin" hanyalah sebuah objek yang mewakili apakah sebuah Thread dapat "tidak diparkir" atau tidak. Dan ini diperiksa oleh Thread itu sendiri (atau de JRE ketika Anda mencoba untuk memarkir Thread) Hal yang "dikonsumsi", saya mengerti bahwa izin hilang dan Thread tidak dinonaktifkan.

Saya pikir Anda harus belajar lebih banyak tentang multithreading .. Anggap saja sebagai dispenser dengan Objek yang disebut "izin". Anda memberitahu Thread untuk memarkir, dan Thread memeriksa dispenser, jika ada "izin", Thread mengambilnya dan pergi (tanpa parkir). Jika tidak ada "izin" di dispenser, Thread akan diparkir sampai "izin" tersedia (dan Anda dapat memberi "izin" di dispenser dengan unpark.

Adapun penggunaan CPU / memori, saya pikir itu tergantung dari OS, dll ...

Vic
sumber