Rumah >Java >javaTutorial >Bagaimana untuk melaksanakan dasar penolakan Java ThreadPoolExecutor?
Prinsip kolam benang adalah seperti berikut:
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.
Kumpulan benang memberikan kami empat dasar penolakan: Dasar Pemanggil, Polisi Abort, Polisi Buang, Polisi Tertua Buang
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:
Kami tahu dari hasil pelaksanaan , Menggunakan strategi AbortPolicy, ralat akan dilaporkan terus apabila tugasan dilaksanakan ke tugasan ketujuh, menyebabkan logik perniagaan berikutnya tidak dilaksanakan. CallerRunsPolicySelepas tugasan ditolak, CallerRunsPolicy akan menggunakan urutan atas yang memanggil fungsi laksana untuk melaksanakan tugas yang ditolak. Contoh berkaitanPengecualian 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]
nama thread: pool-1-thread-5, pelaksanaan: thread 2
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
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:
nama utas: pool-1-thread-1, execution: thread 9
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
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.
DiscardPolicyStrategi 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 DiscardPolicyThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, 5, 10, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(1), new ThreadPoolExecutor.CallerRunsPolicy());
Berdasarkan keputusan pelaksanaan, hanya 6 tugasan telah dilaksanakan, dan tugasan lain telah ditinggalkan. DiscardOldestPolicyDiscardOldestPolicy Apabila tugasan enggan ditambah, tugasan yang mula-mula ditambahkan pada baris gilir tugas akan dibuang dan tugasan baharu akan ditambah. Contoh penerangannama thread: pool-1-thread-1, execution: thread 2
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
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 1, 2, 10, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(2), new ThreadPoolExecutor.CallerRunsPolicy());Hasil pelaksanaan:
nama thread:pool-1-thread- 2, Pelaksanaan: Thread 1
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
当线程池提供的拒绝策略无法满足要求时,我们可以采用自定义的拒绝策略,只需要实现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!