DelayQueue ialah kelas pelaksanaan BlockingQueue tanpa had, yang digunakan untuk meletakkan objek yang melaksanakan antara muka Tertunda .
BlockingQueue ialah baris gilir menyekat, struktur data baris gilir selamat berbilang benang yang disediakan oleh Java Apabila bilangan elemen dalam baris gilir ialah 0, utas yang cuba mendapatkan elemen daripada baris gilir akan disekat atau dibuang. pengecualian.
Baris gilir "tidak terhad" di sini bermakna tiada had atas bilangan elemen dalam baris gilir dan kapasiti baris gilir akan berkembang apabila bilangan elemen bertambah.
DelayQueue melaksanakan antara muka BlockingQueue, jadi ia mempunyai ciri-ciri tidak terhad dan menyekat Selain itu, ciri terasnya ialah:
Tertunda. objek tugasan yang diletakkan dalam baris gilir hanya boleh diambil selepas masa kelewatan dicapai.".
DelayQueue tidak menerima unsur nol
"DelayQueue hanya menerima objek yang melaksanakan antara muka java.util.concurrent.Delayed"
Selepas memahami ciri DelayQueue, kami boleh menggunakannya untuk melaksanakan tugas tertunda dan melaksanakan antara muka java.util.concurrent.Delayed
.
import org.jetbrains.annotations.NotNull; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; /** * 延时订单任务 */ public class OrderDelayObject implements Delayed { private String name; private long delayTime; //延时时间 //实际业务中这里传订单信息对象,我这里只做demo,所以使用字符串了 private String order; public OrderDelayObject(String name, long delayTime, String order) { this.name = name; //延时时间加上当前时间 this.delayTime = System.currentTimeMillis() + delayTime; this.order = order; } //获取延时任务的倒计时时间 @Override public long getDelay(TimeUnit unit) { long diff = delayTime - System.currentTimeMillis(); return unit.convert(diff, TimeUnit.MILLISECONDS); } //延时任务队列,按照延时时间元素排序,实现Comparable接口 @Override public int compareTo(@NotNull Delayed obj) { return Long.compare(this.delayTime, ((OrderDelayObject) obj).delayTime); } @Override public String toString() { Date date = new Date(delayTime); SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return "\nOrderDelayObject:{" + "name=" + name + ", time=" + sd.format(date) + ", order=" + order + "}"; } }
Pesanan dalam kelas di atas ialah objek maklumat pesanan Dalam proses pembangunan perniagaan sebenar, maklumat pesanan perlu dihantar untuk melaksanakan perniagaan pembatalan pesanan (pesanan akan dibatalkan secara automatik jika ia tidak dibayar. selama 30 minit).
Antara muka Tertunda mewarisi daripada antara muka Sebanding, jadi kaedah compareTo perlu dilaksanakan untuk mengisih tugasan tertunda dalam baris gilir mengikut "masa tunda".
Kaedah getDelay ialah kaedah antara muka Tertunda. Melaksanakan kaedah ini menyediakan masa kira detik untuk mendapatkan tugas tertunda
Mula-mula kita memerlukan bekas untuk menyimpan secara kekal kelewatan giliran Tugas, jika ia adalah persekitaran pembangunan Spring, kita boleh melakukan ini.
@Bean("orderDelayQueue") public DelayQueue<OrderDelayObject> orderDelayQueue(){ return new DelayQueue<OrderDelayObject>(); }
Apabila pengguna membuat pesanan, letakkan tugas meletakkan pesanan ke dalam baris gilir kelewatan
@Resource private DelayQueue<OrderDelayObject> orderDelayQueue; //发起订单下单的时候将订单演示对象放入orderDelayQueue orderDelayQueue.add( new OrderDelayObject( "订单延时取消任务", 30 * 60 * 1000, //延时30分钟 "延时任务订单对象信息" ) );
Buka urutan dalam sistem, dapatkan mesej secara berterusan daripada baris gilir, dan kemudian kelewatan mesej diproses . Kaedah ambil DelayQueue
memperoleh objek tugas tertunda daripada baris gilir Jika bilangan elemen baris gilir ialah 0, atau "tugas masa tertunda" belum dicapai, urutan akan disekat.
@Component public class DelayObjectConsumer implements InitializingBean { @Resource private DelayQueue<OrderDelayObject> orderDelayQueue; @Override public void afterPropertiesSet() throws Exception { while (true) { OrderDelayObject task = orderDelayQueue.take(); System.out.println(task.toString()); System.out.println(task.getOrder()); //根据order订单信息,去查询该订单的支付信息 //如果用户没有进行支付,将订单从数据库中关闭 //如果订单并发量比较大,这里可以考虑异步或线程池的方式进行处理 } } }
Perlu diambil perhatian bahawa pemprosesan tugas tertunda bagi gelung while-true di sini dilaksanakan secara berurutan Apabila konkurensi pesanan agak besar, pemprosesan tak segerak perlu dipertimbangkan untuk menyelesaikan operasi penutupan pesanan. Saya sebelum ini telah menulis projek sumber terbuka kumpulan benang yang boleh diperhatikan dan mudah dikonfigurasikan untuk SpringBoot, yang mungkin membantu anda Alamat kod sumber
telah diuji oleh saya dan dimasukkan ke dalam tugas tertunda orderDelayQueue sejam Kemudian dapatkan pemprosesan pelaksanaan yang betul. Ia menunjukkan bahawa pelaksanaan kami adalah betul.
Menggunakan DelayQueue untuk melaksanakan tugas tertunda adalah sangat mudah dan mudah Semua dilaksanakan dalam kod JDK standard, dan tidak perlu memperkenalkan kebergantungan pihak ketiga (ada tidak bergantung pada pelaksanaan redis, pelaksanaan baris gilir mesej, dll.), sangat ringan.
Kelemahannya ialah semua operasi adalah berdasarkan memori aplikasi Sebaik sahaja satu titik kegagalan aplikasi berlaku, data tugas yang tertunda mungkin hilang. Jika konkurensi pesanan adalah sangat besar, kerana DelayQueue tidak terhad, lebih besar volum pesanan, lebih banyak objek dalam baris gilir, yang boleh menyebabkan risiko OOM. Oleh itu, menggunakan DelayQueue untuk melaksanakan tugas tertunda hanya sesuai untuk situasi di mana volum tugas adalah kecil.
Atas ialah kandungan terperinci Bagaimanakah Java DelayQueue melaksanakan tugas tertunda?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!