Rumah  >  Artikel  >  Java  >  Bagaimana untuk melaksanakan dasar penolakan Java ThreadPoolExecutor?

Bagaimana untuk melaksanakan dasar penolakan Java ThreadPoolExecutor?

WBOY
WBOYke hadapan
2023-05-08 15:34:08779semak imbas

    Prinsip Asas Kolam Benang

    Prinsip kolam benang adalah seperti berikut:

    Bagaimana untuk melaksanakan dasar penolakan Java ThreadPoolExecutor?

    Arahan:

    • Jika bilangan utas yang sedang berjalan kurang daripada corePoolSize, buat urutan baharu untuk melaksanakan tugas.

    • Jika benang yang sedang berjalan sama dengan atau lebih daripada corePoolSize, tugasan itu ditambahkan pada baris gilir.

    • Apabila baris gilir tugasan penuh, urutan baharu dicipta dalam kolam bukan teras untuk memproses tugasan.

    • Mencipta utas baharu akan menyebabkan utas yang sedang berjalan melebihi maksimumPoolSize, tugas akan ditolak dan kaedah RejectedExecutionHandler.rejectedExecution() akan dipanggil.

    Dasar penolakan kumpulan benang

    Kumpulan benang memberikan kami empat dasar penolakan: Dasar Pemanggil, Polisi Abort, Polisi Buang, Polisi Tertua Buang

    Polisi Batalkan

    Strategi penolakan lalai dalam ThreadPoolExecutor ialah AbortPolicy secara langsung melemparkan pengecualian adalah seperti berikut

    public static class AbortPolicy implements RejectedExecutionHandler {
        public AbortPolicy() { }
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }

    Penjelasan: Strategi ini sangat mudah dan kasar. Ia secara langsung akan membuang pengecualian RejectedExecutionException tugasan seterusnya.

    Contoh penerangan:

    public class ThreadPoolTest
    {
        public static void main(String[] args)
        {
            ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    2,
                    5,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(1),
                    new ThreadPoolExecutor.AbortPolicy());
            
            //异步执行
            for(int i=0; i<10;i++)
            {
              System.out.println("添加第"+i+"个任务");
              threadPoolExecutor.execute(new TestThread("线程"+i));
            }        
        }
    }
    
    public class TestThread implements Runnable
    {
        private String name;
        public TestThread(String name){
            this.name=name;
        }
        
        @Override
        public void run()
        {
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            System.out.println("thread name:"+Thread.currentThread().getName()+",执行:"+name);
        }
    }

    Hasil pelaksanaan:

    Pengecualian dalam utas "utama" java.util.concurrent.RejectedExecutionException: Task com.skywares.fw.juc .thread.TestThread@55f96302 ditolak daripada java.util.concurrent.ThreadPoolExecutor@3d4eac69[Berjalan, saiz kolam = 5, utas aktif = 5, tugas beratur = 1, tugas selesai = 0]
    di java.util.concurrent. ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
    di java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    di java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    di java.ThreadPoolExecutor.Th.concurrent tor.java : 1369)
    di com.skywares.fw.juc.thread.ThreadPoolTest.main(ThreadPoolTest.java:26)
    nama utas:pool-1-thread-5, pelaksanaan: thread 5
    nama utas : pool-1-thread-2, pelaksanaan: thread 1
    nama thread: pool-1-thread-4, execution: thread 4
    nama thread: pool-1-thread-3, execution: thread 3
    nama utas:pool-1-thread-1, pelaksanaan: thread 0

    nama thread: pool-1-thread-5, pelaksanaan: thread 2

    Kami tahu dari hasil pelaksanaan , Menggunakan strategi AbortPolicy, ralat akan dilaporkan terus apabila tugasan dilaksanakan ke tugasan ketujuh, menyebabkan logik perniagaan berikutnya tidak dilaksanakan.

    CallerRunsPolicy

    Selepas tugasan ditolak, CallerRunsPolicy akan menggunakan urutan atas yang memanggil fungsi laksana untuk melaksanakan tugas yang ditolak.

    Contoh berkaitan

    public class ThreadPoolTest
    {
        public static void main(String[] args)
        {
            ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    2,
                    5,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(1),
                    new ThreadPoolExecutor.CallerRunsPolicy());
            
            //异步执行
            for(int i=0; i<10;i++)
            {
              System.out.println("添加第"+i+"个任务");
              threadPoolExecutor.execute(new TestThread("线程"+i));
            }
        }
    }

    Hasil pelaksanaan:


    Tambahkan tugasan ke-0
    Tambahkan tugasan pertama
    Tambahkan tugasan ke-2
    Tambahkan Tugasan ke-3
    Tambahkan tugasan ke-4
    Tambahkan tugasan ke-5
    Tambahkan tugasan ke-6
    nama utas:utama, pelaksanaan: utas 6
    nama utas:pool- 1-thread-3, pelaksanaan : thread 3
    nama utas: pool-1-thread-1, pelaksanaan: thread 0
    nama thread: pool-1-thread-4, pelaksanaan: thread 4
    nama thread:pool-1-thread -2, pelaksanaan: utas 1
    nama utas: pool-1-thread-5, pelaksanaan: thread 5
    Tambah tugasan ke-7
    Tambah tugasan ke-8
    nama utas:utama,eksekusi:benang 8
    nama utas:pool-1-thread-1,pelaksanaan: thread 7
    nama thread:pool-1-thread-3,execution: thread 2
    Tambahkan tugasan ke-9

    nama utas: pool-1-thread-1, execution: thread 9

    Daripada keputusan pelaksanaan, kita boleh tahu bahawa apabila tugas ke-7 dilaksanakan, disebabkan oleh dasar penolakan Thread pool, tugas ini dilaksanakan oleh utas utama, dan tugas lain akan terus dilaksanakan apabila kumpulan benang melahu. Jadi strategi ini mungkin menyekat utas utama.

    DiscardPolicy

    Strategi penolakan ini agak mudah Tugasan yang ditolak oleh kumpulan benang terus dibuang tanpa membuang pengecualian atau melaksanakan

    Contoh

    . Ubah suai kod di atas dan tukar dasar penolakan kepada DiscardPolicy

     ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    2,
                    5,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(1),
                    new ThreadPoolExecutor.CallerRunsPolicy());

    Hasil pelaksanaan


    mengadakan kejayaan dealStock
    goodsId:telefon bimbit
    nama utas:pool-1- thread -1, pelaksanaan: thread 0
    nama utas: pool-1-thread-4, pelaksanaan: thread 4
    nama thread: pool-1-thread-5, pelaksanaan: thread 5
    nama thread: pool -1-thread-3, pelaksanaan: thread 3
    nama thread: pool-1-thread-2, execution: thread 1

    nama thread: pool-1-thread-1, execution: thread 2

    Berdasarkan keputusan pelaksanaan, hanya 6 tugasan telah dilaksanakan, dan tugasan lain telah ditinggalkan.

    DiscardOldestPolicy

    DiscardOldestPolicy Apabila tugasan enggan ditambah, tugasan yang mula-mula ditambahkan pada baris gilir tugas akan dibuang dan tugasan baharu akan ditambah.

    Contoh penerangan

     ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    1,
                    2,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(2),
                    new ThreadPoolExecutor.CallerRunsPolicy());

    Hasil pelaksanaan:


    Tambahkan tugasan ke-0
    Tambahkan tugasan pertama
    Tambahkan tugasan ke-2
    Tambahkan Tugasan ke-3
    Tambahkan tugasan ke-4
    Tambahkan tugasan ke-5
    majukan kejayaan dealStock
    goodsId: telefon bimbit
    nama utas: pool-1-thread-2, laksanakan: Thread 3
    nama benang:pool-1-thread-1, pelaksanaan: thread 0
    nama thread: pool-1-thread-1, pelaksanaan: thread 2

    nama thread:pool-1-thread- 2, Pelaksanaan: Thread 1

    自定义拒绝策略

    当线程池提供的拒绝策略无法满足要求时,我们可以采用自定义的拒绝策略,只需要实现RejectedExecutionHandler接口即可

    public class CustRejectedExecutionHandler implements RejectedExecutionHandler
    {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
        {
            new Thread(r,"线程:"+new Random().nextInt(10)).start();
        }
    }
    
      ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    1,
                    2,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(2),
                    new CustRejectedExecutionHandler());

    执行结果:

    thread name:客户线程:6,执行:线程5
    thread name:pool-1-thread-1,执行:线程0
    thread name:客户线程:8,执行:线程4
    thread name:pool-1-thread-2,执行:线程3
    thread name:pool-1-thread-1,执行:线程1
    thread name:pool-1-thread-2,执行:线程2

    从执行的结果来看,被拒绝的任务都在客户的新线程中执行。

    小结

    • AbortPolicy:直接抛出异常,后续的任务不会执行

    • CallerRunsPolicy:子任务执行的时间过长,可能会阻塞主线程。

    • DiscardPolicy:不抛异常,任务直接丢弃

    • DiscardOldestPolicy;丢弃最先加入队列的任务

    Atas ialah kandungan terperinci Bagaimana untuk melaksanakan dasar penolakan Java ThreadPoolExecutor?. 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