Apakah ada cara standar yang bagus untuk memanggil metode pemblokiran dengan waktu tunggu di Java? Saya ingin bisa melakukan:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
jika itu masuk akal.
Terima kasih.
java
concurrency
jjujuma
sumber
sumber
Jawaban:
Anda bisa menggunakan Pelaksana:
Jika
future.get
tidak kembali dalam 5 detik, itu melemparTimeoutException
. Batas waktu dapat dikonfigurasi dalam detik, menit, milidetik atau unit apa pun yang tersedia sebagai konstanta dalamTimeUnit
.Lihat JavaDoc untuk detail selengkapnya.
sumber
BlockingMethodCallable
pembuatnya menerima parameter yang ingin Anda teruskanblockingMethod()
dan menyimpannya sebagai variabel anggota (mungkin sebagai variabel final). Kemudian di dalam,call()
berikan parameter tersebut keblockMethod()
.future.cancel(true)
- Metode batal (boolean) dalam tipe Future <Object> tidak berlaku untuk argumen ()Anda bisa menggabungkan panggilan dalam a
FutureTask
dan menggunakan versi waktu tunggu dari get ().Lihat http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
sumber
Lihat juga TimeLimiter Guava yang menggunakan Executor di belakang layar.
sumber
Sungguh luar biasa bahwa orang mencoba menerapkan ini dengan banyak cara. Tapi kenyataannya, TIDAK ADA cara.
Sebagian besar pengembang akan mencoba melakukan panggilan pemblokiran di utas yang berbeda dan memiliki masa depan atau pengatur waktu. TETAPI tidak ada cara di Java untuk menghentikan utas secara eksternal, apalagi beberapa kasus yang sangat spesifik seperti metode Thread.sleep () dan Lock.lockInterruptibly () yang secara eksplisit menangani interupsi utas.
Jadi sebenarnya Anda hanya memiliki 3 opsi umum:
Letakkan panggilan pemblokiran Anda di utas baru dan jika waktunya habis, lanjutkan saja, biarkan utas itu menggantung. Dalam hal ini Anda harus memastikan utas disetel menjadi utas Daemon. Dengan cara ini utas tidak akan menghentikan aplikasi Anda untuk berhenti.
Gunakan API Java yang tidak memblokir. Jadi untuk jaringan misalnya, gunakan NIO2 dan gunakan metode non-blocking. Untuk membaca dari konsol gunakan Scanner.hasNext () sebelum memblokir dll.
Jika panggilan pemblokiran Anda bukan IO, tetapi logika Anda, Anda dapat berulang kali memeriksa untuk
Thread.isInterrupted()
memeriksa apakah panggilan itu terputus secara eksternal, dan melakukan panggilan utas lain di utasthread.interrupt()
pemblokiranKursus tentang konkurensi ini https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
benar-benar mempelajari dasar-dasar tersebut jika Anda benar-benar ingin memahami cara kerjanya di Java. Ini benar-benar berbicara tentang batasan dan skenario tertentu, dan bagaimana melakukannya di salah satu kuliah.
Saya pribadi mencoba memprogram tanpa menggunakan pemblokiran panggilan sebanyak mungkin. Ada toolkit seperti Vert.x misalnya yang membuatnya sangat mudah dan berkinerja baik untuk melakukan IO dan tidak ada operasi IO secara asinkron dan dengan cara yang tidak memblokir.
Saya harap ini membantu
sumber
Ada juga solusi AspectJ untuk itu dengan library aspek jcabi .
Tidak bisa lebih ringkas, tetapi Anda harus bergantung pada AspectJ dan memperkenalkannya dalam siklus proses build Anda, tentunya.
Ada artikel yang menjelaskan lebih lanjut: Batasi Waktu Eksekusi Metode Java
sumber
Perhatikan, perhentian itu tidak digunakan lagi, alternatif yang lebih baik adalah menyetel beberapa tanda boolean volatile, di dalam blockingMethod () periksa dan keluar, seperti ini:
sumber
Coba ini. Solusi yang lebih sederhana. Menjamin jika blok tidak dieksekusi dalam batas waktu. proses ini akan berhenti dan memunculkan pengecualian.
contoh:
sumber
Saya memberi Anda di sini kode lengkap. Sebagai ganti metode yang saya panggil, Anda dapat menggunakan metode Anda:
sumber
Asumsikan
blockingMethod
hanya tidur selama beberapa mili:Solusi saya adalah menggunakan
wait()
dansynchronized
seperti ini:Jadi kamu bisa mengganti
something.blockingMethod(input)
untuk
something.blockingMethod(input, 2000)
Semoga membantu.
sumber
Anda memerlukan implementasi pemutus sirkuit seperti yang ada di proyek keamanan gagal di GitHub.
sumber