❶ Timer的使用異常問題 java
在你的實現自動任務的代碼打一個斷點,debug。應該會在實現具體自動任務的代碼處報錯。然後你研究一下再改代碼,試一下。
❷ c# Timer組件有什麼優缺點
Timer組件就是定時器,每隔設定的時間觸發事件,是線程的一種,而且用timer實現多線程消耗資源非常少,並且可以跨線程使用資源!這是優點,缺點就是沒有線程那麼多的狀態控制,定時器只有啟動和停止,沒有像線程那樣的掛起,睡眠等狀態,定時器用的好能實現出其不意的效果,但如果是比較復雜的多線程項目,還是要用線程實現的,總之各有利弊,要結合實際情況使用。
❸ Timer和ScheledThreadPoolExecutor的區別
在實際應用中,有時候我們需要創建一些個延遲的、並具有周期性的任務,比如,我們希望當我們的程序啟動後每隔1小時就去做一次日誌記錄。在JDK中提供了兩種方法去創建延遲周期性任務。
Timer
Timer是java.util包下的一個類,在JDK1.3的時候被引入,Timer只是充當了一個執行者的角色,真正的任務邏輯是通過一個叫做TimerTask的抽象類完成的,TimerTask也是java.util包下面的類,它是一個實現了Runnable介面的抽象類,包含一個抽象方法run( )方法,需要我們自己去提供具體的業務實現。
Timer類對象是通過其schele方法執行TimerTask對象中定義的業務邏輯,並且schele方法擁有多個重載方法提供不同的延遲與周期性服務。
下面是利用Timer去創建的一個延時周期性任務
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TestTimer {
public static void main(String[] args) {
String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.println("Start time : " + time);
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.println("Now Time : " + time);
}
}; //end task
timer.schele(task, 2000, 3000);
}
}
程序的輸出:
Start time : 21:36:08
Now Time : 21:36:10
Now Time : 21:36:13
Now Time : 21:36:16
Now Time : 21:36:19
ScheledThreadPoolExecutor
在JDK1.5的時候在java.util.concurrent並發包下引入了ScheledThreadPoolExecutor類,引入它的原因是因為Timer類創建的延遲周期性任務存在一些缺陷, ScheledThreadPoolExecutor繼承了ThreadPoolExecutor,並且實現了ScheledExecutorService介面, ScheledThreadPoolExecutor也是通過schele方法執行Runnable任務的。
我們用 ScheledThreadPoolExecutor來實現和上述Timer一樣的功能
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ScheledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestScheledThreadPoolExecutor {
public static void main(String[] args) {
String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.println("Start time : " + time);
ScheledThreadPoolExecutor executor = new ScheledThreadPoolExecutor(5); //創建5個執行線程
Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.println("Now Time : " + time);
}
};
executor.scheleWithFixedDelay(runnable, 2, 3, TimeUnit.SECONDS);
}
}
程序的輸出:
Start time : 22:12:25
Now Time : 22:12:27
Now Time : 22:12:30
Now Time : 22:12:33
Now Time : 22:12:36
這樣看來Timer和 ScheledThreadPoolExecutor好像沒有聲明差別,但是 ScheledThreadPoolExecutor的引入正是由於Timer類存在的一些不足,並且在JDK1.5或更高版本中,幾乎沒有利用繼續使用Timer類,下面說明Timer存在的一些缺點。
單線程
Timer類是通過單線程來執行所有的TimerTask任務的,如果一個任務的執行過程非常耗時,將會導致其他任務的時效性出現問題。而 ScheledThreadPoolExecutor是基於線程池的多線程執行任務,不會存在這樣的問題。
這里我們通過讓Timer來執行兩個TimerTask任務來說明,其中一個TimerTask的執行過程是耗時的,加入需要2秒。
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class SingleThreadTimer {
public static void main(String[] args) {
String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.println("Start time : " + time);
Timer timer = new Timer();
TimerTask task1 = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.println("Task1 time : " + time);
}
};
TimerTask task2 = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.println("task2 time : " + time);
}
};
timer.schele(task1, 2000, 1000);
timer.schele(task2, 2000, 3000);
}
}
這里定義了兩個任務,任務1,程序啟動2秒後每隔1秒運行一次,任務2,程序啟動2秒後,每隔3秒運行1次,然後讓Timer同時運行這兩個任務
程序的輸出如下:
Start time : 22:22:37
Task1 time : 22:22:39
task2 time : 22:22:41
Task1 time : 22:22:41
Task1 time : 22:22:42
task2 time : 22:22:44
Task1 time : 22:22:44
Task1 time : 22:22:45
task2 time : 22:22:47
Task1 time : 22:22:47
Task1 time : 22:22:48
可以分析,無論是任務1還是任務2都沒有按照我們設定的預期進行運行,造成這個現象的原因就是Timer類是單線程的。
Timer線程不捕獲異常
Timer類中是不捕獲異常的,假如一個TimerTask中拋出未檢查異常(P.S: java中異常分為兩類:checked exception(檢查異常)和unchecked exception(未檢查異常),對於未檢查異常也叫RuntimeException(運行時異常). ),Timer類將不會處理這個異常而產生無法預料的錯誤。這樣一個任務拋出異常將會導致整個Timer中的任務都被取消,此時已安排但未執行的TimerTask也永遠不會執行了,新的任務也不能被調度(所謂的「線程泄漏」現象)。
下面就已常見的RuntimeException,數組越界異常,來演示這個缺點:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TestTimerTask {
public static void main(String[] args) {
System.out.println(new SimpleDateFormat("HH:mm:ss").format(new Date()));
Timer timer = new Timer();
TimerTask task1 = new TimerTask() {
@Override
public void run() {
System.out.println("1: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
};
TimerTask task2 = new TimerTask() {
@Override
public void run() {
int[] arr = {1,2,3,4,5};
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int index = (int)(Math.random()*100);
System.out.println(arr[index]);
System.out.println("2: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
};
timer.schele(task1, 2000, 3000);
timer.schele(task2, 2000, 1000);
}
}
程序會在運行過程中拋出數組越界異常,並且整個程序都會被終止,原來完好的任務1也被終止了。
基於絕對時間
Timer類的調度是基於絕對的時間的,而不是相對的時間,因此Timer類對系統時鍾的變化是敏感的,舉個例子,加入你希望任務1每個10秒執行一次,某個時刻,你將系統時間提前了6秒,那麼任務1就會在4秒後執行,而不是10秒後。在 ScheledThreadPoolExecutor,任務的調度是基於相對時間的,原因是它在任務的內部 存儲了該任務距離下次調度還需要的時間(使用的是基於 System#nanoTime實現的相對時間 ,不會因為系統時間改變而改變,如距離下次執行還有10秒,不會因為將系統時間調前6秒而變成4秒後執行)。
基於以上3個弊端,在JDK1.5或以上版本中,我們幾乎沒有理由繼續使用Timer類,ScheledThreadPoolExecutor可以很好的去替代Timer類來完成延遲周期性任務。
❹ JAVA Timer(計時器)和多線程之間的性能問題
個人認為
可以開一個計時器來管理所有的房間,根據不同的房間執行不同的業務,執行的業務通過非同步線程(寫個線程池獲取裡面的線程)去執行(避免任務耗時 阻塞)
❺ java timer太多會影響性能嗎
大量的運用timer時每一個timer又開起一個或是多個線程,每一個線程又要做自己的事情。必然要會影響性能。
❻ java中每個月第一天執行一次任務的定時器如何實現
Date d = new Date();//獲取伺服器的時間。。。
Calendar c= Canlendar.getInstance();
c.setTime(d);
if(c.get(Calendar.DAY_OF_MONTH) == 1) //當前是1號
{
//拿出黨員的入黨日期(年月)同當前月進行比較 如果相同 發送簡訊
// //寫下你的判斷代碼
}
else //當前不是1號 則從下個月1號開始執行定期任務
{
c.set(Calendar.MONTH,c.get(Calendar.MONTH)+ 1);//設置為下月
c.set(Calendar.DAY_OF_MONTH,1);//設置為下月的1號
Timer timer =new Timer();
timer.scheleAtFixedRate(new TimerTask()
{
public void run()
{
//每天都來判斷一下 如果當前日期是1號
////則拿出黨員的入黨日期(年月)同當前月進行比較 如果相同 發送簡訊
//run函數里寫下你的判斷代碼
}},c.getTime(),24* 3600*1000); //每天執行一次run()方法...
}
❼ JAVA 用Timer做定時任務執行,會不會影響項目效率。
會的,但影響不大~比如Android系統就為鬧鍾提供了相應的處理機制
❽ java的timer類如何判斷程序超時呢
參照如下的:
Timer類是用來執行任務的類,它接受一個TimerTask做參數
TimerTask是個抽象類,他擴展了Object並實現了Runnable介面,因此你必須在自己的Task中實現publicvoid run()方法。這也就是我們需要執行的具體任務。
Timer有兩種執行任務的模式,最常用的是schele,它可以以兩種方式執行任務:1:在某個時間(Data),2:在某個固定的時間之後(intdelay).這兩種方式都可以指定任務執行的頻率
我們指定一個線程A,調用對象B.wait(timeout),線程A就會阻塞,直到timeout到了,B醒來會使A繼續執行。
其實Timer類是為多任務定時設計的,在實現裡面,B是一個任務隊列(實現上就是一個array),維護著所有使用當前Timer定時的任務,它們可是一堆貨真價實的線程實例。每次線程A都取隊列中距離當前時間最近的的定時任務,跟當前時間比較,然後wait(timeout)這段時間。線程喚醒的時刻也是隊列中這個定時任務運行的時刻。然後線程繼續取下一個定時任務,繼續wait(timeout)。從這里我們能看出來,每次定時都有額外的時間開銷,比如要維護隊列等,所以Java的Timer類不保證實時。
Timer中最主要由三個部分組成:
任務TimerTask 、 任務隊列: TaskQueue queue 和 任務調試者:TimerThreadthread
Timer對任務的調度是基於絕對時間的。
所有的TimerTask只有一個線程TimerThread來執行,因此同一時刻只有一個TimerTask在執行。
任何一個TimerTask的執行異常都會導致Timer終止所有任務。
由於基於絕對時間並且是單線程執行,因此在多個任務調度時,長時間執行的任務被執行後有可能導致短時間任務快速在短時間內被執行多次或者乾脆丟棄多個任務。
由於Timer/TimerTask有這些特點(缺陷),因此這就導致了需要一個更加完善的任務調度框架來解決這些問題。
默認情況下,只要一個程序的timer線程在運行,那麼這個程序就會保持運行。當然,你可以通過以下四種方法終止一個timer線程:
調用timer的cancle方法。你可以從程序的任何地方調用此方法,甚至在一個timertask的run方法里。
讓timer線程成為一個daemon線程(可以在創建timer時使用newTimer(true)達到這個目地),這樣當程序只有daemon線程的時候,它就會自動終止運行。
當timer相關的所有task執行完畢以後,刪除所有此timer對象的引用(置成null),這樣timer線程也會終止。
調用System.exit方法,使整個程序(所有線程)終止。
❾ 我用Java編一個倒計時器,點開始鍵後子線程啟動顯示數字減少,但暫停和重置按鈕怎麼寫啊
一般來講java裡面5.0或更高的JDK中,定時任務基本上都不再使用Timer。而是使用ScheledThreadPoolExector來替代實現java.util.Timer計時器有管理任務延遲執行("如1000ms後執行任務")以及周期性執行("如每500ms執行一次該任務")。但是,Timer存在一些缺陷,因此你應該考慮使用ScheledThreadPoolExecutor作為代替品,Timer對調度的支持是基於絕對時間,而不是相對時間的,由此任務對系統時鍾的改變是敏感的;ScheledThreadExecutor只支持相對時間。Timer的另一個問題在於,如果TimerTask拋出未檢查的異常,Timer將會產生無法預料的行為。Timer線程並不捕獲異常,所以TimerTask拋出的未檢查的異常會終止timer線程。這種情況下,Timer也不會再重新恢復線程的執行了;它錯誤的認為整個Timer都被取消了。此時,已經被安排但尚未執行的TimerTask永遠不會再執行了,新的任務也不能被調度了。Timer存在的缺陷被ScheledThreadPoolExector鎖彌補替代。由於篇幅原因。
❿ java Timer定時器執行一次後意外終止
java.util.Timer 不推薦使用。
使用 java.util.concurrent.ScheledExecutorService 執行