java多线程队列
A. java多线程共同操作同一个队列,怎么实现
具体代码如下:
B. Java多线程是什么意思
Java多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。
1、继承Thread类实现多线程
继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。例如:
代码说明:
上述代码中Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。
public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。
public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。
public static ScheledExecutorService newScheledThreadPool(int corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
总结:ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。
C. 鍦↗ava 涓澶氱嚎绋嬬殑瀹炵幇鏂规硶链夊摢浜涳纴濡备綍浣跨敤锝烇綖锝烇綖锝烇綖锝烇綖锝烇綖锝烇綖锝烇綖锝烇綖锝烇綖镐
1銆 璁よ瘑Thread鍜孯unnable
Java涓瀹炵幇澶氱嚎绋嬫湁涓ょ嶉斿缎锛氱户镓縏hread绫绘垨钥呭疄鐜癛unnable鎺ュ彛銆俣unnable鏄鎺ュ彛锛屽缓璁鐢ㄦ帴鍙g殑鏂瑰纺鐢熸垚绾跨▼锛屽洜涓烘帴鍙e彲浠ュ疄鐜板氱户镓匡纴鍐典笖Runnable鍙链変竴涓猺un鏂规硶锛屽緢阃傚悎缁ф圹銆傚湪浣跨敤Thread镄勬椂鍊椤彧闇缁ф圹Thread锛屽苟涓拢ew涓涓瀹炰緥鍑烘潵锛岃皟鐢╯tart()鏂规硶鍗冲彲浠ュ惎锷ㄤ竴涓绾跨▼銆
Thread Test = new Thread();
Test.start();
鍦ㄤ娇鐢≧unnable镄勬椂鍊欓渶瑕佸厛new涓涓瀹炵幇Runnable镄勫疄渚嬶纴涔嫔悗钖锷═hread鍗冲彲銆
Test impelements Runnable;
Test t = new Test();
Thread test = new Thread(t);
test.start();
镐荤粨锛歍hread鍜孯unnable鏄瀹炵幇java澶氱嚎绋嬬殑2绉嶆柟寮忥纴runable鏄鎺ュ彛锛宼hread鏄绫伙纴寤鸿浣跨敤runable瀹炵幇java澶氱嚎绋嬶纴涓岖″备綍锛屾渶缁堥兘闇瑕侀氲繃thread.start()𨱒ヤ娇绾跨▼澶勪簬鍙杩愯岀姸镐併
2銆 璁よ瘑Thread镄剆tart鍜宺un
1锛 start锛
鐢╯tart鏂规硶𨱒ュ惎锷ㄧ嚎绋嬶纴鐪熸e疄鐜颁简澶氱嚎绋嬭繍琛岋纴杩欐椂镞犻渶绛夊緟run鏂规硶浣扑唬镰佹墽琛屽畬姣曡岀洿鎺ョ户缁镓ц屼笅闱㈢殑浠g爜銆傞氲繃璋幂敤Thread绫荤殑start()鏂规硶𨱒ュ惎锷ㄤ竴涓绾跨▼锛岃繖镞舵ょ嚎绋嫔勪簬灏辩华锛埚彲杩愯岋级鐘舵侊纴骞舵病链夎繍琛岋纴涓镞﹀缑鍒皊pu镞堕棿鐗囷纴灏卞紑濮嬫墽琛宺un()鏂规硶锛岃繖閲屾柟娉时un()绉颁负绾跨▼浣掳纴瀹冨寘钖浜呜佹墽琛岀殑杩欎釜绾跨▼镄勫唴瀹癸纴Run鏂规硶杩愯岀粨𨱒燂纴姝ょ嚎绋嬮殢鍗崇粓姝銆
2锛 run锛
run()鏂规硶鍙鏄绫荤殑涓涓鏅阃氭柟娉曡屽凡锛屽傛灉鐩存帴璋幂敤Run鏂规硶锛岀▼搴忎腑渚濈劧鍙链変富绾跨▼杩欎竴涓绾跨▼锛屽叾绋嫔簭镓ц岃矾寰勮缮鏄鍙链変竴𨱒★纴杩樻槸瑕侀‘搴忔墽琛岋纴杩樻槸瑕佺瓑寰卹un鏂规硶浣撴墽琛屽畬姣曞悗镓嶅彲缁х画镓ц屼笅闱㈢殑浠g爜锛岃繖镙峰氨娌℃湁杈惧埌鍐欑嚎绋嬬殑鐩镄勚
镐荤粨锛氲皟鐢╯tart鏂规硶鏂瑰彲钖锷ㄧ嚎绋嬶纴钥宺un鏂规硶鍙鏄痶hread镄勪竴涓鏅阃氭柟娉曡皟鐢锛岃缮鏄鍦ㄤ富绾跨▼閲屾墽琛屻
3銆 绾跨▼鐘舵佽存槑
绾跨▼鐘舵佷粠澶х殑鏂归溃𨱒ヨ达纴鍙褰掔粨涓猴细鍒濆嬬姸镐併佸彲杩愯岀姸镐併佷笉鍙杩愯岀姸镐佸拰娑堜骸鐘舵侊纴鍏蜂綋鍙缁嗗垎涓轰笂锲炬墍绀7涓鐘舵侊纴璇存槑濡备笅锛
1锛 绾跨▼镄勫疄鐜版湁涓ょ嶆柟寮忥纴涓鏄缁ф圹Thread绫伙纴浜屾槸瀹炵幇Runnable鎺ュ彛锛屼絾涓岖℃庢牱锛屽綋鎴戜滑new浜唗hread瀹炰緥钖庯纴绾跨▼灏辫繘鍏ヤ简鍒濆嬬姸镐侊绂
2锛 褰撹ュ硅薄璋幂敤浜唖tart()鏂规硶锛屽氨杩涘叆鍙杩愯岀姸镐侊绂
3锛 杩涘叆鍙杩愯岀姸镐佸悗锛屽綋璇ュ硅薄琚镎崭綔绯荤粺阃変腑锛岃幏寰桟PU镞堕棿鐗囧氨浼氲繘鍏ヨ繍琛岀姸镐侊绂
4锛 杩涘叆杩愯岀姸镐佸悗case灏辨瘆杈冨氾纴澶ц嚧链夊备笅𨱍呭舰锛
路run()鏂规硶鎴杕ain()鏂规硶缁撴潫钖庯纴绾跨▼灏辫繘鍏ョ粓姝㈢姸镐侊绂
路褰撶嚎绋嬭皟鐢ㄤ简镊韬镄剆leep()鏂规硶鎴栧叾浠栫嚎绋嬬殑join()鏂规硶锛屽氨浼氲繘鍏ラ樆濉炵姸镐(璇ョ姸镐佹棦锅沧㈠綋鍓岖嚎绋嬶纴浣嗗苟涓嶉喷鏀炬墍鍗犳湁镄勮祫婧)銆傚綋sleep()缁撴潫鎴杍oin()缁撴潫钖庯纴璇ョ嚎绋嬭繘鍏ュ彲杩愯岀姸镐侊纴缁х画绛夊緟OS鍒嗛厤镞堕棿鐗囷绂
路褰撶嚎绋嫔垰杩涘叆鍙杩愯岀姸镐(娉ㄦ剰锛岃缮娌¤繍琛)锛屽彂鐜板皢瑕佽皟鐢ㄧ殑璧勬簮琚阌佺墷(synchroniza,lock)锛屽皢浼氱珛鍗宠繘鍏ラ挛姹犵姸镐侊纴绛夊緟銮峰彇阌佹爣璁(杩欐椂镄勯挛姹犻噷涔熻稿凡缁忔湁浜嗗叾浠栫嚎绋嫔湪绛夊緟銮峰彇阌佹爣璁帮纴杩欐椂瀹冧滑澶勪簬阒熷垪鐘舵侊纴镞㈠厛鍒板厛寰)锛屼竴镞︾嚎绋嬭幏寰楅挛镙囱板悗锛屽氨杞鍏ュ彲杩愯岀姸镐侊纴绛夊緟OS鍒嗛厤CPU镞堕棿鐗囷绂
路褰撶嚎绋嬭皟鐢╳ait()鏂规硶钖庝细杩涘叆绛夊緟阒熷垪(杩涘叆杩欎釜鐘舵佷细閲婃斁镓鍗犳湁镄勬墍链夎祫婧愶纴涓庨樆濉炵姸镐佷笉钖)锛岃繘鍏ヨ繖涓鐘舵佸悗锛屾槸涓嶈兘镊锷ㄥ敜阅掔殑锛屽繀椤讳緷闱犲叾浠栫嚎绋嬭皟鐢╪otify()鎴杗otifyAll()鏂规硶镓嶈兘琚鍞ら啋(鐢变簬notify()鍙鏄鍞ら啋涓涓绾跨▼锛屼絾鎴戜滑鐢变笉鑳界‘瀹氩叿浣揿敜阅掔殑鏄鍝涓涓绾跨▼锛屼篃璁告垜浠闇瑕佸敜阅掔殑绾跨▼涓嶈兘澶熻鍞ら啋锛屽洜姝ゅ湪瀹为檯浣跨敤镞讹纴涓鑸閮界敤notifyAll()鏂规硶锛屽敜阅掓湁镓绾跨▼)锛岀嚎绋嬭鍞ら啋钖庝细杩涘叆阌佹睁锛岀瓑寰呰幏鍙栭挛镙囱般
路褰撶嚎绋嬭皟鐢╯top鏂规硶锛屽嵆鍙浣跨嚎绋嬭繘鍏ユ秷浜$姸镐侊纴浣嗘槸鐢变簬stop鏂规硶鏄涓嶅畨鍏ㄧ殑锛屼笉榧揿姳浣跨敤锛屽ぇ瀹跺彲浠ラ氲繃run鏂规硶閲岀殑𨱒′欢鍙橀氩疄鐜扮嚎绋嬬殑stop銆
D. 璇剧▼璁捐¢樼洰锛屽氱嚎绋嬬紪绋嬶细鍖婚櫌闂ㄨ瘖妯℃嫙锛屾兂鐢╦ava瀹炵幇锛屾眰澶х炴寚镣
鍏稿瀷镄勭敓浜ц呮秷璐硅呮ā鍨嬨
浜呜Вj5镄勫苟鍙戝簱锛岄偅涓骞跺彂搴扑腑链夐傚悎缁勪欢瀹炵幇銆
濡傛灉涓崭简瑙o纴杩欎箞𨱒ワ细
鍒涘缓涓涓阒熷垪锛屾ら槦鍒楄佹眰绾跨▼瀹夊叏锛屽傛灉阒熷垪涓虹┖鍒欐秷璐硅呴樆濉炪傚傛灉阒熷垪杈惧埌镆愪釜链澶у硷纴鍒欓樆濉炵敓浜ц呫
阒熷垪鐢锛屾櫘阃氱殑list鎴栧疄鐜板ソ镄勯槦鍒楀寘瑁呮垚绾跨▼瀹夊叏镄勚
鐢╯ynchronized钖屾ュ师鏂规硶鎴栦唬镰佸潡銆
鍐欎竴涓鎴杗涓绾跨▼锛屾ā𨰾熺梾浜猴纴鎺挜槦锷炵悊涓氩姟锛屽线涓婇溃镄勯槦鍒椾腑娣诲姞鏁版嵁銆
褰撹揪鍒伴槦鍒楃殑链澶у圭Н锛岄樆濉烇纴绛夊緟鐢熶骇钥呯嚎绋嫔彇鏁版嵁銆
阒诲烇细makerLock.wait();//铏氭嫙链轰细鍑鸿╃嚎绋嬫寕璧凤纴鍏跺疄灏辨槸镎崭綔绯荤粺锛屼缭瀛桦綋鍓岖嚎绋嫔湪cpu涓婄殑杩愯岀姸镐併傚啀鍑鸿╃嚎绋嬫e湪浣跨敤镄刢pu璧勬簮锛屽崰鐢ㄧ殑鍐呭瓨涓崭细閲婃斁銆
寰阒熷垪鎻掑叆鏁版嵁镄勬椂鍊欙纴锲犱负涓岖煡阆撴槸钖︽湁娑堣垂钥呭勪簬绛夊緟鐘舵侊纴阃氱煡娑堣垂钥咃细
customerLock.notifyAll();//铏氭嫙链鸿皟搴︽秷璐硅呯嚎绋嬭繍琛岋纴瀹为檯涓婃槸镎崭綔绯荤粺锛屾妸淇濆瓨镄勬秷璐硅呯嚎绋嬬姸镐侊纴浠庢柊锷犺浇鍒瘫pu涓鎺ョ潃杩愯屻傛帴镌杩愯岀嚎绋嬫槸浠绘剰镄勶纴鍙栧喅浜庝笉钖屾搷浣灭郴缁熺殑绾跨▼璋冨害绠楁硶銆
娑堣垂钥呯嚎绋嬭诲彇涓涓鏁版嵁钖庯纴瑕侀氱煡鐢熶骇钥咃纴鍙浠ョ户缁锛岄亾鐞嗗悓涓婏细
makerLock.notifyAll();
阒熷垪涓锛屾棤鏁版嵁鍙璇荤殑镞跺欙细
customerLock.wait();//铡熺悊钖屼笂锛
链钖庢敞镒忥纴鐢熶骇钥呰窡娑堣垂钥呬娇鐢ㄤ简涓や釜涓嶅悓镄勫硅薄阌併俵ock.wait()镄勪娇鐢ㄦ柟娉曟槸杩欐牱镄勶细
synchronized(lock){
......
while(condition==true){
lock.wait();
}
......
Objecto=queen.pop();
lock.notifyAll();
}
链钖庡惎锷╪涓绾跨▼璇婚槦鍒楋纴妯℃嫙锷炵悊涓氩姟镄勭獥鍙o绂n涓绾跨▼鍐欓槦鍒楋纴妯℃嫙䦅呬汉鎺挜槦銆
鏂扮嚎绋嫔簱涔熸湁璺熻佺嚎绋嫔簱瀵瑰簲镄勬柟娉曪纴鏂扮嚎绋嫔簱链夌嚎绋嫔畨鍏ㄧ殑楂樻晥阒熷垪銆傛病链変笂闱㈤夯鐑︼纴浣嗕笂闱㈠啓镄勬槸鐞呜В鏂扮嚎绋嬫暟鎹缁撴瀯涓庡疄鐜扮殑锘虹銆
packagecom.;
importjava.util.LinkedList;
importjava.util.List;
importjava.util.Random;
publicclassTestThread2{
//缂揿啿涓婇檺
privatelongbufsize;
//缂揿啿
privateList<String>buf;
publicTestThread2(){
bufsize=5;
buf=newLinkedList<String>();
}
//鐢熶骇钥呰皟鐢
publicvoidput(Strings){
//妯℃嫙鐢熶骇钥呰窡涓崭笂娑堣垂钥
/*
try{
Thread.sleep(100);
}catch(InterruptedExceptione){
}
*/
synchronized(this){
//瓒呰繃阒熷垪闄愬埗灏辩瓑寰
while(buf.size()==bufsize){
System.out.println("阒熷垪宸叉弧锛岀敓浜ц:"+Thread.currentThread().getId()+"寮濮嬬瓑寰呫");
try{
this.wait();
}catch(InterruptedExceptione){
}
}
buf.add(s);
//阃氱煡娑堣垂钥
this.notifyAll();
}
}
//娑堣垂钥呰皟鐢
synchronizedpublicStringtake(){
//妯℃嫙娑堣垂钥呰窡涓崭笂鐢熶骇钥
try{
Thread.sleep(100);
}catch(InterruptedExceptione){
}
Strings=null;
synchronized(this){
while(buf.size()==0){
System.out.println("阒熷垪涓虹┖锛屾秷璐硅:"+Thread.currentThread().getId()+"寮濮嬬瓑寰呫");
try{
this.wait();
}catch(InterruptedExceptione){
}
}
//鍙栧厛鏀惧叆镄勫厓绱狅纴骞剁Щ闄
s=buf.get(0);
buf.remove(0);
//阃氱煡鐢熶骇钥
this.notifyAll();
}
returns;
}
publicstaticvoidmain(String[]args){
//镊宸卞疄鐜扮殑锛屽畨鍏ㄩ槦鍒
finalTestThread2tt=newTestThread2();
//鐢熶骇钥
Threadp=newThread(newRunnable(){
@Override
publicvoidrun(){
while(!Thread.currentThread().isInterrupted()){
Randomr=newRandom();
tt.put(String.valueOf(r.nextInt(10)));
}
}
});
//娑堣垂钥
Threadc1=newThread(newRunnable(){
@Override
publicvoidrun(){
while(!Thread.currentThread().isInterrupted()){
System.out.println("绾跨▼锛"+Thread.currentThread().getId()+"銮峰彇鍒版暟鎹"+tt.take());
}
}
});
Threadc2=newThread(newRunnable(){
@Override
publicvoidrun(){
while(!Thread.currentThread().isInterrupted()){
System.out.println("绾跨▼锛"+Thread.currentThread().getId()+"銮峰彇鍒版暟鎹"+tt.take());
}
}
});
p.start();
c1.start();
c2.start();
try{
p.join();
c1.join();
c2.join();
}catch(InterruptedExceptione){
}
}
}
E. 多线程的java 程序如何编写
Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
F. java线程组,线程池,线程队列分别是什么有什么区别
你好,我可以给你详细解释一下:
线程组表示一个线程的集合。此外,线程组也可以包含其他线程组。线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组。
允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息。
线程池:我们可以把并发执行的任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程。只要池里有空闲的线程,任务就会分配给一个线程执行。在线程池的内部,任务被插入一个阻塞队列(Blocking Queue ),线程池里的线程会去取这个队列里的任务。当一个新任务插入队列时,一个空闲线程就会成功的从队列中取出任务并且执行它。
线程池经常应用在多线程服务器上。每个通过网络到达服务器的连接都被包装成一个任务并且传递给线程池。线程池的线程会并发的处理连接上的请求。以后会再深入有关 Java 实现多线程服务器的细节。
线程队列:是指线程处于拥塞的时候形成的调度队列
排队有三种通用策略:
直接提交。工作队列的默认选项是 SynchronousQueue,它将任务直接提交给线程而不保持它们。在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败,因此会构造一个新的线程。此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
无界队列。使用无界队列(例如,不具有预定义容量的 LinkedBlockingQueue)将导致在所有corePoolSize 线程都忙时新任务在队列中等待。这样,创建的线程就不会超过 corePoolSize。(因此,maximumPoolSize的值也就无效了。)当每个任务完全独立于其他任务,即任务执行互不影响时,适合于使用无界队列;例如,在 Web页服务器中。这种排队可用于处理瞬态突发请求,当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
有界队列。当使用有限的 maximumPoolSizes时,有界队列(如 ArrayBlockingQueue)有助于防止资源耗尽,但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低 CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果它们是 I/O边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量。
G. 线程池-参数篇:2.队列
多线程环境中,通过队列可以很容易实现线程间数据共享,比如经典的“生产者”和“消费者”模型中,通过队列可以很便利地实现两者之间的数据共享;同时作为BlockingQueue的使用者,我们不需要关心什么时候需要阻塞线程,什么时候需要唤醒线程,因为这一切BlockingQueue的实现者都给一手包办了。
基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定长数组,以便缓存队列中的数据对象,另外还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置。
ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,由此也意味着两者无法真正并行运行,而在创建ArrayBlockingQueue时,我们还可以控制对象的内部锁是否采用公平锁,默认采用非公平锁。
按照实现原理来分析,ArrayBlockingQueue完全可以采用分离锁,从而实现生产者和消费者操作的完全并行运行。
基于链表的阻塞队列,其内部也维持着一个数据缓冲队列(由一个链表构成),当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。
对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。
ArrayBlockingQueue和LinkedBlockingQueue间还有一个明显的不同之处在于,前者在插入或删除元素时不会产生或销毁任何额外的对象实例,而后者则会生成一个额外的Node对象。这在长时间内需要高效并发地处理大批量数据的系统中,其对于GC的影响还是存在一定的区别。如果没有指定其容量大小,LinkedBlockingQueue会默认一个类似无限大小的容量(Integer.MAX_VALUE),这样的话,如果生产者的速度一旦大于罩伍消费者的速度,也许还没有等到队列满阻塞产生,系统内存就有可能已被消耗殆尽了。
ArrayBlockingQueue和LinkedBlockingQueue是两个最普通也是最常用的阻塞队列,一般情况下,在处理多线程间的生产者消费者问题,使用这两个类足以。
DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。DelayQueue是一个没有大小限制的队列,因此往队列中插入数据的操作(生产者)永远不会被阻塞,而只有获取数据的操作(消费者)才会被阻塞。
DelayQueue用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。注意:不能将null元素放置到这种队列中。
Delayed 是一种混合风格的接口,用来标记那些应该在给定延迟时间之后执行的对象。Delayed扩展了Comparable接口,比较的基准为延时的时间值,Delayed接口的实现类getDelay的返回值应为固定宴闷冲值(final)。DelayQueue内部是使用PriorityQueue实现的。
考虑以下场景:
一种笨笨的办法就是,使用一个后台线程,遍历所有对象,挨个检查。这种笨笨的办法简单好用,但是对象数量过多时,可能存在性能问题,检查间隔时间不好设置,间隔时间过大,影响精确度,多小则存在效率问题。而且做不到按超时的时间顺序处理。
这场景,使用DelayQueue最适合了,详情查看 DelayedQueue学习笔记 ; 精巧好用的DelayQueue
基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compator对象来决定),需要注意PriorityBlockingQueue并不会阻塞数据生产者晌歼,而只会在没有可消费的数据时,阻塞数据的消费者。
使用时,若生产者生产数据的速度快于消费者消费数据的速度,随着长时间的运行,可能会耗尽所有的可用堆内存空间。在实现PriorityBlockingQueue时,内部控制线程同步的锁采用的是公平锁。
SynchronousQueue是一个内部只能包含零个元素的队列。插入元素到队列的线程被阻塞,直到另一个线程从队列中获取元素。同样,如果线程尝试获取元素并且当前没有线程在插入元素,则该线程将被阻塞,直到有线程将元素插入队列
声明一个SynchronousQueue有公平模式和非公平模式,区别如下:
参考: Java多线程-工具篇-BlockingQueue
12. SynchronousQueue