java延時隊列
① java timer 設置了延遲1秒每56秒執行一次。
由於你沒有上傳代碼 沒法具體分析 只能說下Timer的使用方法 你可以參考下 看看自己使用有沒有問題 沒有的話 提供下代碼和錯誤日誌 才能具體分析
方法摘要
void
cancel()
終止此計時器,丟棄所有當前已安排的任務。
int
purge()
從此計時器的任務隊列中移除所有已取消的任務。
void
schele(TimerTask task,
Date time)
安排在指定的時間執行指定的任務。
void
schele(TimerTask task,
Date firstTime,
long period)
安排指定的任務在指定的時間開始進行重復的固定延遲執行。
void
schele(TimerTask task,
long delay)
安排在指定延遲後執行指定的任務。
void
schele(TimerTask task,
long delay, long period)
安排指定的任務從指定的延遲後開始進行重復的固定延遲執行。
void
scheleAtFixedRate(TimerTask task,
Date firstTime,
long period)
安排指定的任務在指定的時間開始進行重復的固定速率執行。
void
scheleAtFixedRate(TimerTask task,
long delay, long period)
安排指定的任務在指定的延遲後開始進行重復的固定速率執行。
② 到底什麼是消息隊列Java中如何實現消息隊列
「消息隊列」是在消息的傳輸過程中保存消息的容器。和我們學過的LinkedHashMap,TreeSet等一樣,都是容器。既然是容器,就有有自己的特性,就像LinkedHashMap是以鍵值對存儲。存取順序不變。而消息隊列,看到隊列就可以知道。這個容器裡面的消息是站好隊的,一般遵從先進先出原則。
java中已經為我們封裝好了很多的消息隊列。在java 1.5版本時推出的java.util.concurrent中有很多現成的隊列供我們使用。特性繁多,種類齊全。是你居家旅遊開發必備QAQ。
下面簡單列舉這個包中的消息隊列
:阻塞隊列 BlockingQueue
數組阻塞隊列 ArrayBlockingQueue
延遲隊列 DelayQueue
鏈阻塞隊列 LinkedBlockingQueue
具有優先順序的阻塞隊列 PriorityBlockingQueue
同步隊列 SynchronousQueue
阻塞雙端隊列 BlockingDeque
鏈阻塞雙端隊列 LinkedBlockingDeque
不同的隊列不同的特性決定了隊列使用的時機,感興趣的話你可以詳細了解。具體的使用方式我就不贅述了
③ java延時函數
在Java中有時候需要使程序暫停一點時間,稱為延時。普通延時用Thread.sleep(int)方法,這很簡單。它將當前線程掛起指定的毫秒數。如
Java
代碼復制內容到剪貼板
try
{
Thread.currentThread().sleep(1000);//毫秒
}
catch(Exception
e){}
在這里需要解釋一下線程沉睡的時間。sleep()方法並不能夠讓程序"嚴格"的沉睡指定的時間。例如當使用5000作為sleep()方法的參數時,線
程可能在實際被掛起5000.001毫秒後才會繼續運行。當然,對於一般的應用程序來說,sleep()方法對時間控制的精度足夠了。
但是如果要使用精確延時,最好使用Timer類:
Java
代碼復制內容到剪貼板
Timer
timer=new
Timer();//實例化Timer類
timer.schele(new
TimerTask(){
public
void
run(){
System.out.println("退出");
this.cancel();}},500);//五百毫秒
這種延時比sleep精確。上述延時方法只運行一次,如果需要運行多次,
使用timer.schele(new
MyTask(),
1000,
2000);
則每間隔2秒執行MyTask()
④ java 延遲輸出問題
Java中主要有兩種方法來實現延遲,即:Thread和Timer
1、普通延時用Thread.sleep(int)方法,這很簡單。它將當前線程掛起指定的毫秒數。如
try
{
Thread.currentThread().sleep(1000);//毫秒
}
catch(Exception e){}
在這里需要解釋一下線程沉睡的時間。sleep()方法並不能夠讓程序"嚴格"的沉睡指定的時間。例如當使用5000作為sleep()方法的參數時,線 程可能在實際被掛起5000.001毫秒後才會繼續運行。當然,對於一般的應用程序來說,sleep()方法對時間控制的精度足夠了。
2、但是如果要使用精確延時,最好使用Timer類:
Timer timer=new Timer();//實例化Timer類
timer.schele(new TimerTask(){
public void run(){
System.out.println("退出");
this.cancel();}},500);//五百毫秒
這種延時比sleep精確。上述延時方法只運行一次,如果需要運行多次, 使用timer.schele(new MyTask(), 1000, 2000); 則每間隔2秒執行MyTask()
⑤ java中如何是方法延遲執行
new Thread(new Runnable() {
public void run() {
while(true) {
repaint();
Thread.sleep(500);
}
}
}).start();
這樣就沒錯誤了。
要用延遲的話,不妨試試java.util.Timer().
new java.util.Timer().schele(new TimerTask(){
public void run() {
//這里寫延遲後要運行的代碼
repaint();
//如果只要這個延遲一次,用cancel方法取消掉.
this.cancel();
}}, 3000);
//參考參考java幫助文擋,也可以以固定間隔連續執行.
⑥ java代碼延遲30秒
setTimeout()在js類中的使用方法
setTimeout (表達式,延時時間)
setTimeout(表達式,交互時間)
延時時間/交互時間是以豪秒為單位的(1000ms=1s)
setTimeout 在執行時,是在載入後延遲指定時間後,去執行一次表達式,僅執行一次
setTimeout 在執行時,它從載入後,每隔指定的時間就執行一次表達式
1,基本用法:
執行一段代碼:
var i=0;
setTimeout("i+=1;alert(i)",1000);
執行一個函數:
var i=0;
setTimeout(function(){i+=1;alert(i);},1000);
//注意比較上面的兩種方法的不同。
下面再來一個執行函數的:
var i=0;
function test(){
i+=1;
alert(i);
}
setTimeout("test()",1000);
也可以這樣:
setTimeout(test,1000);
總結:
setTimeout的原型是這樣的:
iTimerID = window.setTimeout(vCode, iMilliSeconds [, sLanguage])
setTimeout有兩種形式
setTimeout(code,interval)
setTimeout(func,interval,args)
其中code是一個字元串
func是一個函數.
注意"函數"的意義,是一個表達式,而不是一個語句.
比如你想周期性執行一個函數
function a(){
//...
}
可寫為
setTimeout("a()",1000)
或
setTimeout(a,1000)
這里注意第二種形式中,是a,不要寫成a(),切記!!!
展開來說,不管你這里寫的是什麼,如果是一個變數,一定是一個指向某函數的變數;如果是個函數,那它的返回值就 要是個函數
2,用setTimeout實現setInterval的功能
思路很簡單,就是在一個函數中調用不停執行自己,有點像遞歸
var i=0;
function xilou(){
i+=1;
if(i>10){alert(i);return;}
setTimeout("xilou()",1000);
//用這個也可以
//setTimeout(xilou,1000);
}
⑦ java 延時語句如何使用需要用頭文件嗎
在Java中有時候需要使程序暫停一點時間,稱為延時。普通延時用Thread.sleep(int)方法,這很簡單。它將當前線程掛起指定的毫秒數。如
Java 代碼
try
{
Thread.currentThread().sleep(1000);//毫秒
}
catch(Exception e){}
在這里需要解釋一下線程沉睡的時間。
sleep()方法並不能夠讓程序"嚴格"的沉睡指定的時間。
例如當使用5000作為sleep()方法的參數時,線 程可能在實際被掛起5000.001毫秒後才會繼續運行。當然,對於一般的應用程序來說,sleep()方法對時間控制的精度足夠了。
但是如果要使用精確延時,最好使用Timer類:
Java 代碼
Timer timer=new Timer();//實例化Timer類
timer.schele(new TimerTask(){
public void run(){
System.out.println("退出");
this.cancel();}},500);//五百毫秒
這種延時比sleep精確。上述延時方法只運行一次,如果需要運行多次, 使用timer.schele(new MyTask(), 1000, 2000);
則每間隔2秒執行MyTask()
⑧ 用java編一個隊列
自己寫了個簡單的實現
class Queue<E>{
private Object[] integerQueue;//用來當隊列
public int tail;//隊尾
public int size;//隊的長度,也可以設置一個默認值,溢出時從新申請
public Queue(int size){
integerQueue=new Object[size];
this.size=size;
tail=-1;
}
/**
* 將元素插入隊列
* @return 如果該元素已添加到此隊列,則返回 true;否則返回 false
*/
public boolean offer(E e){
if(tail <size-1){
tail++;
this.integerQueue[tail]=e;
return true;
}else{
return false;
}
}
/**
* 獲取並移除此隊列的頭,如果此隊列為空,則返回 null。
*/
public E poll(){
Object tmp;
if(tail>=0){
tmp=this.integerQueue[tail];
tail--;
return (E)tmp;
}else{
return null;
}
}
}
⑨ 網易傳媒技術團隊:消息中間件實現延遲隊列的應用與實踐
早期需要延遲處理的業務場景,更多的是通過定時任務掃表,然後執行滿足條件的記錄,具有頻率高、命中低、資源消耗大的缺點。隨著消息中間件的普及,延遲消息可以很好的處理這種場景,本文主要介紹延遲消息的使用場景以及基於常見的消息中間件如何實現延遲隊列,最後給出了一個在網易公開課使用延遲隊列的實踐。
1、有效期:限時活動、拼團。。。
2、超時處理:取消超時未支付訂單、超時自動確認收貨。。。
4、重試:網路異常重試、打車派單、依賴條件未滿足重試。。。
5、定時任務:智能設備定時啟動。。。
1、RabbitMQ
1)簡介:基於AMQP協議,使用Erlang編寫,實現了一個Broker框架
a、Broker:接收和分發消息的代理伺服器
b、Virtual Host:虛擬主機之間相互隔離,可理解為一個虛擬主機對應一個消息服務
c、Exchange:交換機,消息發送到指定虛擬機的交換機上
d、Binding:交換機與隊列綁定,並通過路由策略和routingKey將消息投遞到一個或多個隊列中
e、Queue:存放消息的隊列,FIFO,可持久化
f、Channel:信道,消費者通過信道消費消息,一個TCP連接上可同時創建成百上千個信道,作為消息隔離
2)延遲隊列實現:RabbitMQ的延遲隊列基於消息的存活時間TTL(Time To Live)和死信交換機DLE(Dead Letter Exchanges)實現
a、TTL:RabbitMQ支持對隊列和消息各自設置存活時間,取二者中較小的值,即隊列無消費者連接或消息在隊列中一直未被消費的過期時間
b、DLE:過期的消息通過綁定的死信交換機,路由到指定的死信隊列,消費者實際上消費的是死信隊列上的消息
3)缺點:
a、配置麻煩,額外增加一個死信交換機和一個死信隊列的配置
b、脆弱性,配置錯誤或者生產者消費者連接的隊列錯誤都有可能造成延遲失效
2、RocketMQ
1)簡介:來源於阿里,目前為Apache頂級開源項目,使用Java編寫,基於長輪詢的拉取方式,支持事務消息,並解決了順序消息和海量堆積的問題
a、Broker:存放Topic並根據讀取Procer的提交日誌,將邏輯上的一個Topic分多個Queue存儲,每個Queue上存儲消息在提交日誌上的位置
b、Name Server:無狀態的節點,維護Topic與Broker的對應關系以及Broker的主從關系
2)延遲隊列實現:RocketMQ發送延時消息時先把消息按照延遲時間段發送到指定的隊列中(rocketmq把每種延遲時間段的消息都存放到同一個隊列中),然後通過一個定時器進行輪訓這些隊列,查看消息是否到期,如果到期就把這個消息發送到指定topic的隊列中
3)缺點:延遲時間粒度受限制(1s/5s/10s/30s/1m/2m/3m/4m/5m/6m/7m/8m/9m/10m/20m/30m/1h/2h)
3、Kafka
1)簡介:來源於Linkedin,目前為Apache頂級開源項目,使用Scala和Java編寫,基於zookeeper協調的分布式、流處理的日誌系統,升級版為Jafka
2)延遲隊列實現:Kafka支持延時生產、延時拉取、延時刪除等,其基於時間輪和JDK的DelayQueue實現
a、時間輪(TimingWheel):是一個存儲定時任務的環形隊列,底層採用數組實現,數組中的每個元素可以存放一個定時任務列表
b、定時任務列表(TimerTaskList):是一個環形的雙向鏈表,鏈表中的每一項表示的都是定時任務項
c、定時任務項(TimerTaskEntry):封裝了真正的定時任務TimerTask
d、層級時間輪:當任務的到期時間超過了當前時間輪所表示的時間范圍時,就會嘗試添加到上層時間輪中,類似於鍾表就是一個三級時間輪
e、JDK DelayQueue:存儲TimerTaskList,並根據其expiration來推進時間輪的時間,每推進一次除執行相應任務列表外,層級時間輪也會進行相應調整
3)缺點:
a、延遲精度取決於時間格設置
b、延遲任務除由超時觸發還可能被外部事件觸發而執行
4、ActiveMQ
1)簡介:基於JMS協議,Java編寫的Apache頂級開源項目,支持點對點和發布訂閱兩種模式。
a、點對點(point-to-point):消息發送到指定的隊列,每條消息只有一個消費者能夠消費,基於拉模型
b、發布訂閱(publish/subscribe):消息發送到主題Topic上,每條消息會被訂閱該Topic的所有消費者各自消費,基於推模型
2)延遲隊列實現:需要延遲的消息會先存儲在JobStore中,通過非同步線程任務JobScheler將到達投遞時間的消息投遞到相應隊列上
a、Broker Filter:Broker中定義了一系列BrokerFilter的子類構成攔截器鏈,按順序對消息進行相應處理
b、ScheleBroker:當消息中指定了延遲相關屬性,並且jobId為空時,會生成調度任務存儲到JobStore中,此時消息不會進入到隊列
c、JobStore:基於BTree存儲,key為任務執行的時間戳,value為該時間戳下需要執行的任務列表
d、JobScheler:取JobStore中最小的key執行(調度時間最早的),執行時間<=當前時間,將該任務列表依次投遞到所屬的隊列,對於需要重復投遞和投遞失敗的會再次存入JobStore中。
註: 此處JobScheler的執行時間間隔可動態變化,默認0.5s,有新任務時會立即執行(Object->notifyAll())並設置時間間隔為0.1s,沒有新任務後,下次執行時間為最近任務的調度執行時間。
3)缺點:投遞到隊列失敗,將消息重新存入JobStore,消息調度執行時間=系統當前時間+延遲時間,會導致消息被真實投遞的時間可能為設置的延遲時間的整數倍
5、Redis
1)簡介:基於Key-Value的NoSQL資料庫,由於其極高的性能常被當作緩存來使用,其數據結構支持:字元串、哈希、列表、集合、有序集合
2)延遲隊列實現:Redis的延遲隊列基於有序集合,score為執行時間戳,value為任務實體或任務實體引用
3)缺點:
a、實現復雜,本身不支持
b、完全基於內存,延遲時間長浪費內存資源
6、消息隊列對比
1、公開課延遲隊列技術選型
1)業務場景:關閉超時未支付訂單、限時優惠活動、拼團
2)性能要求:訂單、活動、拼團 數據量可控,上述MQ均能滿足要求
3)可靠性:使用ActiveMQ、RabbitMQ、RocketMQ作為延遲隊列更普遍
4)可用性:ActiveMQ、RocketMQ自身支持延遲隊列功能,且目前公開課業務中使用的中間件為ActiveMQ和Kafka
5)延遲時間靈活:活動的開始和結束時間比較靈活,而RocketMQ時間粒度較粗,Kafka會依賴時間格有精度缺失
結論: 最終選擇ActiveMQ來作為延遲隊列
2、業務場景:關閉未支付訂單
1)關閉微信未支付訂單
2)關閉IOS未支付訂單
3、ActiveMQ使用方式
1)activemq.xml中支持調度任務
2)發送消息時,設置message的延遲屬性
其中:
a、延遲處理
AMQ_SCHEDULED_DELAY:設置多長時間後,投遞給消費者(毫秒)
b、重復投遞
AMQ_SCHEDULED_PERIOD:重復投遞時間間隔(毫秒)
AMQ_SCHEDULED_REPEAT:重復投遞次數
c、指定調度計劃
AMQ_SCHEDULED_CRON:corn正則表達式
4、公開課使用中進行的優化
1)可靠性:針對實際投遞時間可能翻倍的問題,結合ActiveMQ的重復投遞,在消費者邏輯中做冪等處理來保證延遲時間的准確性
2)可追溯性:延遲消息及消費情況做資料庫冗餘存儲
3)易用性:業務上定義好延遲枚舉類型,直接使用JmsDelayTemplate發送,無需關心數據備份和參數等細節
1、無論是基於死信隊列還是基於數據先存儲後投遞,本質上都是將延遲待發送的消息數據與正常訂閱的隊列分開存儲,從而降低耦合度
2、無論是檢查隊頭消息TTL還是調度存儲的延遲數據,本質上都是通過定時任務來完成的,但是定時任務的觸發策略以及延遲數據的存儲方式決定了不同中間件之間的性能優劣
張浩,2018年加入網易傳媒,高級Java開發工程師,目前在網易公開課主要做支付財務體系、版本迭代相關的工作。
⑩ JAVA中 如何使用延遲
Java中主要有兩種方法來實現延遲,即:Thread和Timer
1、普通延時用Thread.sleep(int)方法,這很簡單。它將當前線程掛起指定的毫秒數。如
try
{
Thread.currentThread().sleep(1000);//毫秒
}
catch(Exception e){}
在這里需要解釋一下線程沉睡的時間。sleep()方法並不能夠讓程序"嚴格"的沉睡指定的時間。例如當使用5000作為sleep()方法的參數時,線 程可能在實際被掛起5000.001毫秒後才會繼續運行。當然,對於一般的應用程序來說,sleep()方法對時間控制的精度足夠了。
2、但是如果要使用精確延時,最好使用Timer類:
Timer timer=new Timer();//實例化Timer類
timer.schele(new TimerTask(){
public void run(){
System.out.println("退出");
this.cancel();}},500);//五百毫秒
這種延時比sleep精確。上述延時方法只運行一次,如果需要運行多次, 使用timer.schele(new MyTask(), 1000, 2000); 則每間隔2秒執行MyTask()