Rumah  >  Artikel  >  Java  >  Bagaimana untuk menyelesaikan masalah konkurensi tinggi InterruptedException dalam java

Bagaimana untuk menyelesaikan masalah konkurensi tinggi InterruptedException dalam java

WBOY
WBOYke hadapan
2023-04-30 08:46:061602semak imbas

Kata Pengantar

InterruptedException mungkin tidak semudah yang anda fikirkan!

Apabila kita memanggil kaedah wait() bagi objek Java atau kaedah sleep() bagi thread, kita perlu menangkap dan mengendalikan pengecualian InterruptedException. Jika kami mengendalikan InterruptedException secara tidak betul, akibat yang tidak dijangka akan berlaku!

Kes Program

Sebagai contoh, dalam kod program berikut, kelas InterruptedTask melaksanakan antara muka Runnable Dalam kaedah run(), pemegang benang semasa diperolehi dan dalam gelung while(true), Gunakan kaedah isInterrupted() untuk mengesan sama ada benang semasa terganggu Jika benang semasa terganggu, keluar dari gelung while(true) Pada masa yang sama, dalam gelung while(true). juga merupakan barisan kod Thread.sleep(100) dan tangkap pengecualian InterruptedException.

Keseluruhan kod ditunjukkan di bawah.

package io.binghe.concurrent.lab08;
/**
 * @author binghe
 * @version 1.0.0
 * @description 线程测试中断
 */
public class InterruptedTask implements Runnable{
    @Override
    public void run() {
        Thread currentThread = Thread.currentThread();
        while (true){
            if(currentThread.isInterrupted()){
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Niat asal kod di atas adalah untuk menyemak sama ada benang telah diganggu melalui kaedah isInterrupted() dan keluar dari gelung while jika ia terganggu. Utas lain mengganggu utas pelaksanaan dengan memanggil kaedah interrupt() bagi utas pelaksanaan Pada masa ini, bit bendera sampukan bagi utas pelaksanaan ditetapkan, supaya currentThread.isInterrupted() kembali benar, supaya gelung sementara boleh. keluar.

Ini kelihatan baik! Tetapi adakah ia benar-benar begitu? Kami mencipta kelas InterruptedTest untuk ujian, kodnya adalah seperti berikut.

package io.binghe.concurrent.lab08;
/**
 * @author binghe
 * @version 1.0.0
 * @description 测试线程中断
 */
public class InterruptedTest {
    public static void main(String[] args){
        InterruptedTask interruptedTask = new InterruptedTask();
        Thread interruptedThread = new Thread(interruptedTask);
        interruptedThread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        interruptedThread.interrupt();
    }
}

Kami menjalankan kaedah utama seperti yang ditunjukkan di bawah.

Bagaimana untuk menyelesaikan masalah konkurensi tinggi InterruptedException dalam java

Analisis Masalah

Kod di atas dengan jelas memanggil kaedah interrupt() thread untuk mengganggu thread, tetapi ia tidak memberi kesan. Sebabnya ialah apabila kaedah run() thread dilaksanakan, ia disekat pada sleep(100) pada kebanyakan masa Apabila thread lain mengganggu thread execution dengan memanggil kaedah interrupt() thread execution, InterruptedException akan dicetuskan dengan a. kebarangkalian tinggi, apabila pengecualian InterruptedException dicetuskan, JVM akan mengosongkan bit bendera gangguan pada masa yang sama Oleh itu, kaedah currentThread.isInterrupted() yang dinilai dalam run() pada masa ini akan mengembalikan palsu. dan gelung semasa semasa tidak akan keluar.

Sekarang analisis masalah telah dikosongkan, bagaimana untuk mengganggu urutan dan keluar dari program?

Penyelesaian Masalah

Cara yang betul untuk mengendalikannya hendaklah selepas menangkap pengecualian dalam gelung while(true) dalam kaedah run() dalam InterruptedTask class Tetapkan semula bit bendera interrupt, jadi kod yang betul untuk kelas InterruptedTask adalah seperti berikut.

package io.binghe.concurrent.lab08;
/**
 * @author binghe
 * @version 1.0.0
 * @description 中断线程测试
 */
public class InterruptedTask implements Runnable{
    @Override
    public void run() {
        Thread currentThread = Thread.currentThread();
        while (true){
            if(currentThread.isInterrupted()){
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
                currentThread.interrupt();
            }
        }
    }
}

Seperti yang anda lihat, kami telah menambah baris kod baharu dalam blok kod tangkapan yang menangkap pengecualian InterruptedException.

currentThread.interrupt();

Ini membolehkan kami selepas menangkap pengecualian InterruptedException, kami boleh menetapkan semula bit bendera gangguan pada utas, sekali gus mengganggu urutan yang sedang dilaksanakan.

Kami menjalankan kaedah utama kelas InterruptedTest sekali lagi seperti yang ditunjukkan di bawah.

Bagaimana untuk menyelesaikan masalah konkurensi tinggi InterruptedException dalam java

Ringkasan

Berhati-hati semasa mengendalikan InterruptedException Jika InterruptedException dilemparkan apabila memanggil kaedah interrupt() bagi utas pelaksanaan untuk mengganggu urutan pelaksanaan, Apabila pengecualian InterruptedException dicetuskan, JVM akan mengosongkan bit bendera gangguan pada urutan pelaksanaan pada masa yang sama Pada masa ini, apabila kaedah isInterrupted() bagi utas pelaksanaan dipanggil, false akan dikembalikan.

Pada masa ini, cara yang betul untuk mengendalikannya ialah dengan menangkap pengecualian InterruptedException dalam kaedah run() bagi utas pelaksanaan dan menetapkan semula bit bendera gangguan (iaitu, dalam blok kod tangkapan yang menangkap Pengecualian InterruptedException, panggil semula kaedah interrupt() Thread semasa).

Atas ialah kandungan terperinci Bagaimana untuk menyelesaikan masalah konkurensi tinggi InterruptedException dalam java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam