프로그래밍 프로세스 중에 간단한 타이밍 작업을 실행 해야하는 경우 복잡한 제어를 수행 할 필요가 없습니다. JDK에서 타이머 타이밍 작업을 사용하여이를 달성 할 수 있습니다. 다음 LZ는 원리, 예제 및 타이머 결함에 따라 Java 타이머 타이머를 분석합니다.
1. 소개
Java에서는 타이머 및 타이머스크 클래스에서 완전한 타이밍 작업을 완료해야합니다. 이것이 API에서 정의 된 방법입니다. 타이머 : 나중에 스레드가 수행하는 작업을 배열하는 데 사용하는 도구. 작업을 한 번 실행하거나 반복적으로 실행할 수 있습니다. Timertask에서 예정된 작업 : 타이머가 실행되거나 반복되는 작업으로. 타이머는 배경 스레드에서 지정된 작업을 실행하는 데 사용되는 타이머 도구이며 타이머가 계획 할 수있는 작업을 나타내는 초록 클래스 인 Timertask입니다.
타이머 클래스 <br /> 도구 클래스 타이머에서는 4 가지 생성자 방법이 제공됩니다. 각 생성자는 타이머 스레드를 시작합니다. 동시에 타이머 클래스는 여러 스레드가 외부 동기화없이 단일 타이머 객체를 공유 할 수 있으므로 타이머 클래스는 스레드 안전입니다. 그러나 각 타이머 개체는 단일 배경 스레드에 해당하므로 모든 타이머 작업을 순서대로 실행하는 데 사용되므로 일반적으로 스레드 작업의 실행에 소비 된 시간은 매우 짧아야합니다. 그러나 특수한 상황으로 인해 특정 타이머 작업의 실행 시간이 너무 길어서 타이머 작업 실행 스레드를 "독점적으로" "이후의 실행을 기다려야하므로 후속 작업의 실행을 지연시키고 이러한 작업을 함께 쌓을 수 있습니다. 나중에 특정 상황을 분석 할 것입니다.
프로그램이 타이머를 초기화하면 설정 시간에 따라 타이밍 작업이 실행됩니다. 타이머는 다음과 같이 다른 상황에 적응하기 위해 여러 개의 과부하가있는 일정 방법을 제공합니다.
일정 (Timertask Task, Date Time) : 지정된 시간에 지정된 작업의 실행을 예약하십시오.
일정 (Timertask 작업, 날짜 초기, 장기) : 지정된 작업을 지정된 시간에 반복 고정 지연 실행을 시작하도록 지정된 작업을 예약하십시오.
일정 (Timertask Task, Long Delay) : 지정된 지연 후에 지정된 작업을 실행할 예정입니다.
일정 (Timertask 작업, 긴 지연, 장기) : 지정된 지연 후 지정된 지연된 지정된 작업을 예약하십시오.
동시에, ScheduleAtfixedRate 메소드도 과부하됩니다. ScheduLeatFixedRate 방법은 스케줄과 동일하지만 초점은 다르며 차이는 나중에 분석됩니다.
scheduleatfixedrate (Timertask Task, Date Firsttime, Long 기간) : 지정된 시간에 고정 된 속도로 반복적으로 실행하도록 지정된 작업을 예약하십시오.
ScheduleAtfixEdrate (Timertask Task, Long Delay, Long 기간) : 지정된 지연 후 반복 고정 속도 실행을 시작하도록 지정된 작업을 예약하십시오.
타이머스크
Timertask 클래스는 타이머가 실행되거나 반복되는 작업으로 배열 된 추상 클래스입니다. 초록 메소드 run () 메소드가 있으며 해당 타이머 작업에서 수행 할 작업을 수행하는 데 사용됩니다. 따라서 각 특정 작업 클래스는 Timertask를 상속 한 다음 run () 메소드를 무시해야합니다.
또한 두 가지 비 임금 방법이 있습니다.
Boolean cancel () :이 타이머 작업을 취소하십시오.
Long ScheduleDexecutionTime () :이 작업을 가장 최근에 실행 한 예정된 실행 시간을 반환합니다.
2. 예
2.1. 타이밍 작업을 실행할 지연 시간을 지정하십시오
공개 클래스 TimerTest01 {타이머 타이머; public timertest01 (int time) {timer = new Timer (); TIMER.SCEDULE (New TimertAskTest01 (), Time * 1000); } public static void main (String [] args) {System.out.println ( "타이머 시작 ..."); New Timertest01 (3); }} public class timertasktest01은 Timertask {public void run () {system.out.println ( "Time 's UP !!!"); }} 실행 결과 :
첫 번째 인쇄 : 타이머 시작 ...
3 초 만에 인쇄 : 시간이 올라! !!!
2.2. 지정된 시간에 타이밍 작업을 실행하십시오
공개 클래스 TIMERTEST02 {타이머 타이머; public timertest02 () {날짜 시간 = gettime (); System.out.println ( "시간 지정 시간 =" + 시간); 타이머 = 새로운 타이머 (); TIMER.SCEDULE (New TimertAskTest02 (), 시간); } 공개 날짜 gettime () {Calendar Calendar = Calendar.getInstance (); calendar.set (calendar.hour_of_day, 11); calendar.set (calendar.minute, 39); calendar.set (calendar.second, 00); 날짜 시간 = calendar.gettime (); 반환 시간; } public static void main (String [] args) {new Timertest02 (); }} public class timertasktest02는 timertask {@override public void run () {system.out.println ( "지정된 시간에 스레드 작업 실행 ..."); }} 시간이 11:39:00에 도달하면 스레드 작업이 실행됩니다. 물론 그 시간보다 더 큰 경우에도 실행됩니다! ! 실행 결과는 다음과 같습니다.
지정된 시간 시간 = tue 6 월 10 일 11:39:00 CST 2014
지정된 시간에 스레드 작업 실행 ...
2.3. 지정된 시간을 지연 시키면 지정된 간격 시간에 타이밍 작업이 실행됩니다.
공개 클래스 TIMERTEST03 {타이머 타이머; public timertest03 () {timer = new Timer (); TIMER.SCEDULE (New TimertAskTest03 (), 1000, 2000); } public static void main (String [] args) {new Timertest03 (); }} public class timertasktest03 Timertask {@override public void run () {date date = new Date (this.scheduledExecutionTime ()); System.out.println ( "이 스레드를 실행하는 시간은 다음과 같습니다." + date); }} 실행 결과 :
이 스레드를 실행하는 시간은 다음과 같습니다. tue 6 월 10 일 21:19:47 CST 2014
이 스레드를 실행하는 시간은 다음과 같습니다. tue 6 월 10 일 21:19:49 CST 2014
이 스레드를 실행하는 시간은 다음과 같습니다. tue 6 월 10 일 21:19:51 CST 2014
이 스레드를 실행하는 시간은 다음과 같습니다. tue 6 월 10 일 21:19:53 CST 2014
이 스레드를 실행하는 시간은 다음과 같습니다. tue 6 월 10 일 21:19:55 CST 2014
이 스레드를 실행하는 시간은 다음과 같습니다. tue 6 월 10 일 21:19:57 CST 2014
................
이 스레드 작업의 경우 작업을 중지하지 않으면 계속 실행됩니다.
위의 세 가지 예에서 LZ는 간단히 보여 주었고 ScheduleAtfixedRate 메소드의 예를 설명하지 않았습니다. 실제로이 방법은 일정 방법과 동일합니다!
2.4. 일정을 분석하고 스케줄링 픽스 드레이트를 분석하십시오
1), 일정 (타이머스크 작업, 날짜 시간), 일정 (타임 스케이스 작업, 장기 지연)
두 가지 방법 모두 지정된 ScheduleDexecutionTime <= SystemCurrentTime이 있으면 작업이 즉시 실행됩니다. 과도한 작업 실행으로 인해 ScheduleDexecutionTime이 변경되지 않습니다.
2) 일정 (타이머스크 작업, 날짜 초기, 장기), 일정 (타이머스크 작업, 장기 지연, 장기)
이 두 가지 방법은 위의 두 가지 방법과 약간 다릅니다. 앞에서 언급했듯이 이전 작업이 오랫동안 실행되므로 타이머 타이머 작업이 지연됩니다. 이 두 가지 방법에서, 각 실행 된 작업의 예약 시간은 이전 작업의 실제 시간, 즉 ScheduledExecutionTime (n+1) = realexecutionTime (N)+기간 시간에 따라 변경됩니다. 즉, Nth 작업이 일부 상황으로 인해이 실행 시간 프로세스를 일으키고 SystemCurrentTime> = ScheduleDexecutionTime (N+1)이면 N+1 작업이며 시간 때문에 실행되지 않습니다. 실행 전에 NTH 작업이 실행되기를 기다릴 것입니다. 이는 필연적으로 N+2 실행 구현 ScheduleDexecutionTime 릴리스 및 변경, 즉 ScheduledExecutionTime (N+2) = REAlexecutionTime (N+1)+기간 시간으로 이어집니다. 따라서이 두 가지 방법은 스토리지 간격 시간의 안정성에 더 많은주의를 기울입니다.
3) scheduleatfixedrate (Timertask 작업, 날짜 최초, 장기), ScheduLeatFixEdrate (Timertask 작업, 장기 지연, 장기)
앞에서 언급했듯이 ScheduLeatFixEdrate 및 일정 방법의 초점은 다릅니다. 일정 방법은 저장 간격 시간의 안정성에 중점을 두는 반면 ScheduLeatFixedRate 방법은 실행 주파수의 안정성을 유지하는 데 더 중점을 둡니다. 왜 그렇게 말합니까? 그 이유는 다음과 같습니다. 일정 방법에서, 이전 작업의 지연은 그 후 타이밍 작업의 지연을 유발하는 반면 ScheduLeatFixedRate 메소드는 그렇지 않습니다. NTH 작업의 실행 시간이 너무 길면 SystemCurrentTime> = ScheduleDexecutionTime (N+1)이 있으면 즉시 N+1 작업을 실행할 때까지 기다리지 않습니다. 따라서 ScheduLeatFixedRate 메소드의 실행 시간의 계산 방법은 스케줄과 다르지만 ScheduleDexecutionTime (N) = FirstExecuteTime +N*기간 시간이 다르며 계산 방법은 영원히 변경되지 않습니다. 따라서 ScheduLeatFixedRate는 실행 주파수를 안정적으로 유지하는 데 더 중점을 둡니다.
3. 타이머의 결함
3.1. 타이머의 결함
타이머 타이머는 시간 (지정된 시간에 작업 실행), 지연 (5 초에 작업 지연) 및 주기적으로 작업을 실행할 수 있지만 (1 초에 작업을 실행) 타이머에는 약간의 단점이 있습니다. 우선, 타이머의 스케줄링 지원은 상대 시간이 아닌 절대 시간을 기준으로하므로 시스템 시간의 변화에 매우 민감합니다. 둘째, 타이머 스레드는 예외를 포착하지 않습니다. 확인되지 않은 예외가 Timertask에 의해 던져지면 타이머 스레드가 종료됩니다. 동시에 타이머는 스레드의 실행을 재개하지 않으며 전체 타이머 스레드가 취소 될 것이라고 실수로 믿습니다. 동시에, 아직 실행되지 않은 것으로 예정된 Timertask는 더 이상 실행되지 않으며 새로운 작업을 예약 할 수 없습니다. 따라서 Timertask가 확인되지 않은 예외를 던지면 타이머가 예측할 수없는 동작을 생성합니다.
1) 타이머 관리 시간 지연 결함 <br /> 이전 타이머는 시간이 정해진 작업을 실행할 때만 하나의 스레드 작업 만 생성합니다. 스레드가 여러 개있는 경우 스레드 중 하나가 스레드 작업 실행 시간이 어떤 이유로 든 너무 길고 두 작업 사이의 간격이 그 사이의 시간을 초과하면 일부 결함이 발생합니다.
공개 클래스 TIMERTEST04 {개인 타이머 타이머; 대중의 긴 시작; public timertest04 () {this.timer = new Timer (); start = system.currenttimeMillis (); } public void timerone () {timer.schedule (new Timertask () {public void run () {system.out.println ( "timerone 호출, 시간 :" + (System.currentTimeMillis () - 시작); try {strook.sleep (4000); thread sleeps 3000} (e.pricted e); }}}}, 1000); } public void timertwo () {timer.schedule (new Timertask () {public void run () {system.out.println ( "TimerOne 호출, 시간 :" + (System.CurrentTimeMillis ());}}, 3000); } public static void main (string [] args)은 예외를 던집니다 {Timertest04 test = new Timertest04 (); Test.TimerOne (); test.timertwo (); }} 우리의 정상적인 사고에 따르면, Timertwo는 3 초 이후에 실행되어야하며 결과는 다음과 같습니다.
타이머 론은 시간 : 1001
타이머 론은 시간 : 3001
그러나 상황은 내 기대에 위배되었습니다. 타이머 론은 잠을 자고 (4000) 잠을 자고 4 초, 타이머는 타이머 안에있어 TimeOne이 간격을 초과하는 데 필요한 시간이 발생합니다. 결과 :
타이머로 호출, 시간 : 1000
타이머 론은 시간 : 5000
2) 타이머는 예외 결함을 던졌습니다
Timertask가 Runtimeexception을 던지면 타이머가 모든 작업을 종료합니다. 다음과 같이 :
공개 클래스 TIMERTEST04 {개인 타이머 타이머; public timertest04 () {this.timer = new Timer (); } public void timerone () {timer.schedule (new Timertask () {public void run () {wrach new runtimeexception ();}}, 1000); } public void timertwo () {timer.schedule (new Timertask () {public void run () {system.out.println ( "Ill I Execute It?");}}, 1000); } public static void main (String [] args) {Timertest04 test = new Timertest04 (); Test.TimerOne (); test.timertwo (); }} 실행 결과 : 타이머 론은 예외를 던져 Timertwo 작업이 종료됩니다.
스레드에서의 예외 "Timer-0"java.lang.runtimeexception에서 com.chenssy.timer.timertest04 $ 1.Run (timertest04.java:25)에서 java.util.mainloop (timer.java:555) at java.util.timerthread.run (timer.java:505).
타이머의 결함의 경우 ScheduledThreadPooleExecutor를 교체로 간주 할 수 있습니다. 타이머는 절대 시간을 기준으로하며 시스템 시간에 더 민감하지만 ScheduledThreadPooleExecutor는 상대 시간을 기준으로합니다. 타이머는 내부적으로 단일 스레드이며 ScheduledThreadPooleExecutor는 내부적으로 스레드 풀이므로 여러 작업의 동시 실행을 지원할 수 있습니다.
3.2. ScheduleDexecutorService로 타이머를 교체하십시오
1) 문제 해결 :
공개 클래스 ScheduleDexecutorTest {private scheduledExecutorService scheduexec; 대중의 긴 시작; ScheduleDexecutortest () {this.scheduexec = executors.newscheduledthreadpool (2); this.start = System.CurrentTimeMillis (); } public void timerone () {schedulexec.schedule (new runnable () {public void run () {system.out.println ( "Timerone, Time :" + (System.CurrentTimeMillis () - 시작); {stride.sleep (4000);}}}}}}}}}} { }, 1000, timeUnit.milliseconds); } public void timertwo () {scheduleeexec.schedule (new runnable () {public void run () {system.out.println ( "timertwo, time :" + (system.currenttimeMillis () - 시작);}}, 2000, timeunit.milliseconds); } public static void main (String [] args) {scheduledexecutortest test = new ScheduledExecutortest (); Test.TimerOne (); test.timertwo (); }} 실행 결과 :
타이머 론, 시간 : 1003
TIMERTWO, 시간 : 2005
2) 문제를 해결하십시오
공개 클래스 ScheduleDexecutorTest {private scheduledExecutorService scheduexec; 대중의 긴 시작; ScheduleDexecutortest () {this.scheduexec = executors.newscheduledthreadpool (2); this.start = System.CurrentTimeMillis (); } public void timerone () {schedulexec.schedule (new Runnable () {public void run () {throw new runtimeexception ();}}, 1000, timeUnit.milliseconds); } public void timertwo () {scheduleeexec.scheduleatfixedrate (new runnable () {public void run () {system.out.println ( "Timertwo Invoked .....");}}, 2000,500, timeUnit.milliseconds); } public static void main (String [] args) {scheduledexecutortest test = new ScheduledExecutortest (); Test.TimerOne (); test.timertwo (); }} 실행 결과 :
Timertwo는 ... Timertwo가 호출했습니다 ... Timertwo는 ... Timertwo가 호출했습니다 ... Timertwo는 호출했습니다 ... Timertwo는 호출했습니다 ... Timertwo는 ... Timertwo는 호출했습니다 ... Timertwo는 ............ Timertwo 호출 ...............................
위는이 기사의 전체 내용입니다. 이것은 Java 타이밍 작업에 관한 것입니다. 나는 그것이 당신의 학습에 도움이되기를 바랍니다.