1. 개요
주로 타이머 및 타이머 스탁 클래스의 두 클래스를 사용하여 Java에서 정기적으로 작업을 실행하는 기능을 구현합니다. 타이머는 지정된 계획에 따라 지정된 작업을 백그라운드 스레드에서 실행하는 데 사용됩니다.
Timertask는 추상 클래스이며 하위 클래스는 타이머로 계획 할 수있는 작업을 나타냅니다. 실행될 특정 코드는 TimerTask를 구현 해야하는 실행 방법으로 작성됩니다.
2. 가장 간단한 예를 살펴 보겠습니다
코드를 통해 설명해 봅시다
import java.text.simpledateformat; import java.util.date; import java.util.timer; import java.util.timertask; public class timerdemo {public static string getCurrentTime () {date date = new Date (); simpledateformat sdf = new simpledateformat ( "yyyy-mm-dd hh : mm : ss"); 반환 sdf.format (날짜); } public static void main (String [] args)은 InterruptedException {System.out.println ( "메인 시작 :"+getCurrentTime ()); STARTTIMER (); Thread.sleep (1000*5); // 5 초 동안 잠을 자고 System.out.println ( "메인 엔드 :"+getCurrentTime ()); } public static void startTimer () {timertask task = new Timertask () {@override public void run () {system.out.println ( "task run :"+getCurrentTime ()); }}; 타이머 타이머 = 새로운 타이머 (); TIMER.SCEDULE (작업, 0); }}인쇄를 통해 관찰 정보를 용이하게하기 위해 메인 방법에 인쇄 정보를 추가하고 주 스레드를 잠들기 위해 stride.sleep라고 불렀습니다. 또한 현재 날짜를 얻기 위해 GetCurrentTime 메소드가 클래스에 추가됩니다.
위의 코드에서 STARTTIMER 메소드에서 TIMERTASK 객체 (타이머에 의해 실행되는 작업)가 생성되고 타이머 개체가 생성되고 타이머 클래스의 일정 메소드가 호출됩니다. 타이머 클래스에는 매개 변수가 다른 여러 스케줄 방법이 있습니다. 여기서 사용되는 것은 다음과 같습니다.
공개 무효 일정 (Timertask 작업, 장기 지연)
이 방법의 의미는 타이머가 시간 지연 (밀리 초) 후에 작업 작업을 실행하는 것입니다. 지연이 음수이거나 0 인 경우 작업이 즉시 수행됩니다. 그리고 그것은 일회성 실행 작업이며, 그 후에는 이후에 실행되지 않거나 예정되어 있지 않습니다.
타이머 클래스의 경우 다음과 같이 동일한 함수가있는 메소드도 제공됩니다.
공개 무효 일정 (Timertask 작업, 날짜 시간)
이 방법과 위의 방법의 차이점은 위의 방법이 실행이 일정 기간 동안 지연되도록 지정 하고이 방법은 특정 시점에서 실행이 수행되도록 지정한다는 것입니다. 시스템의 현재 시간이 매개 변수 시간에 지정된 시간을 초과하면 작업이 즉시 실행됩니다.
위의 코드를 실행할 때이 프로그램은 다음과 비슷한 두 가지 정보를 즉시 인쇄한다는 것을 알았습니다.
메인 시작 : 2016-01-13 22:23:18
작업 실행 : 2016-01-13 22:23:18
여기서 일정 메소드로 전달하는 지연 매개 변수 값은 0이므로 작업이 즉시 실행되므로 두 문장 인쇄 시간은 동일합니다. 들어오는 지연 값을 직접 변경하여 출력 정보의 변경 사항을 확인할 수 있습니다. 약 5 초 (즉, 수면 시간) 후에는 1 개의 메시지를 계속 인쇄했습니다.
메인 엔드 : 2016-01-13 22:23:23
정보 인쇄 시간은 위의 진술보다 5 초 부족하며, 이는 수면 설정과 일치하며 매우 합리적입니다.
그러나 우리는 매우 흥미로운 현상을 발견 할 것이며, 그 과정이 종료되지 않을 것임을 알게 될 것입니다. 현재 메인 메인 스레드가 끝났습니다. 즉, 타이머가 작업을 완료 한 후에는 나중에 실행되기를 기다리는 작업이 없더라도 타이머에서 생성 된 배경 스레드가 즉시 종료되지 않음을 의미합니다. 관련 Java Doc 문서를 확인하고 타이머 스레드가 적극적으로 종료되지 않고 쓰레기 수집을 기다릴 필요가 있지만 Java의 쓰레기 수집은 코드 자체에 의해 제어 될 수 없지만 가상 시스템에 의해 제어됩니다.
연구 후, 타이머 객체를 만들고 타이머 타이머 = new Timer ()를 실행할 때; 문, 타이머 스레드가 생성됩니다. 다시 말해, 위의 코드에 Timer.schedule (task, 0)이 없더라도; 성명서, 프로그램은 종료되지 않습니다. 나는 이것이 매우 불합리하다고 생각합니다. 타이머 클래스의 소스 코드를 다시 연구 한 결과 부울 매개 변수가있는 생성자도 있음을 발견했습니다.
공개 타이머 (부울 Isdaemon)
매개 변수 이름에서 볼 수 있듯이 매개 변수 값이 true 인 경우 타이머가 만든 타이머 스레드는 데몬 스레드입니다. 데몬 스레드의 의미는 Java 프로세스의 모든 작업자 스레드가 종료되면 데몬 스레드가 자동으로 종료된다는 것입니다.
현재 위의 예에서 타이머 객체를 생성하기위한 코드를 변경하면 다음과 같은 예입니다. 타이머 타이머 = new Timer (true);
프로그램이 실행되면 메인 스레드 (기본 스레드가 데몬 스레드가 아니라 작업자 스레드)가 완료된 후 프로그램이 종료됩니다. 즉, 타이머 스레드도 종료 함을 의미합니다. 즉, 매개 변수를 추가 한 후 생성 된 데몬 스레드는 데몬 스레드입니다.
그러나 문제는 실제 응용 프로그램 시나리오에서 많은 작업자 스레드가 실행되며 프로그램이 부담없이 종료되지 않는다는 것입니다. 그렇다면 타이머가 즉시 종료되거나 닫히기를 원한다면 어떻게해야합니까? 우리는 이것을 아래에 소개 할 것입니다.
3. 타이머 출구
타이머 클래스는 타이머를 취소하는 취소 방법을 제공합니다. 취소 방법을 호출하면이 타이머가 종료되고 현재 예정된 모든 작업을 폐기합니다. 이것은 현재 실행중인 작업을 방해하지 않습니다 (존재하는 경우). 타이머가 종료되면 실행 스레드도 종료되며 더 이상 작업을 예약 할 수 없습니다.
이 타이머라는 타이머 작업의 실행 메소드 내 에서이 메소드를 호출하면 실행중인 작업 이이 타이머가 실행 한 마지막 작업임을 절대적으로 보장 할 수 있습니다. 이 방법은 반복적으로 호출 될 수 있습니다. 그러나 두 번째 및 후속 통화는 유효하지 않습니다.
다른 예제 코드를 살펴 보겠습니다.
import java.text.simpledateformat; import java.util.date; import java.util.timer; import java.util.timertask; public class timerdemo {public static string getCurrentTime () {date date = new Date (); simpledateformat sdf = new simpledateformat ( "yyyy-mm-dd hh : mm : ss"); 반환 sdf.format (날짜); } public static void main (String [] args)은 InterruptedException {System.out.println ( "메인 시작 :"+getCurrentTime ()); 타이머 타이머 = STARTTIMER (); Thread.sleep (1000*5); // 5 초 동안 잠을 자고 System.out.println ( "메인 엔드 :"+getCurrentTime ()); TIMER.CANCEL (); } public static timer startTimer () {timertask task = new TimerTask () {@override public void run () {system.out.println ( "task run :"+getCurrentTime ()); }}; 타이머 타이머 = 새로운 타이머 (); TIMER.SCEDULE (작업, 0); 리턴 타이머; }} 프로그램을 실행하는 것은 위의 예제의 출력과 정확히 동일합니다. 차이점은 기본 방법이 끝날 때입니다. 프로세스가 적극적으로 종료되므로 타이머 스레드가 닫혔습니다.
기본 방법에서 취소 방법을 호출하기 때문입니다. Timertask의 실행 메소드에서 취소 메소드를 호출하지 않는 경우 실행하려는 작업이 시작되거나 완료되었는지 확인하십시오. 그렇지 않으면 작업이 실행되기 시작하지 않은 경우. 호출 취소만으로 모든 작업이 실행되지 않습니다. 예를 들어 위의 코드,
예를 들어, 위 코드에서 기본 메소드에서 취소 메소드를 호출하지 않지만 Timer.Schedule (task, 0)을 추가하십시오. STARTTIMER 메소드의 명령문 및 TIMER.CANCEL ()을 추가합니다. 실행 후, 타이머 작업이 실행되기 전에 취소되므로 타이머 작업이 실행되지 않는다는 것을 알게됩니다.
4. 정기적으로 작업을 실행합니다
위의 예에서, 우리는 일회성 작업, 즉 타이머 시간이 왔습니다. 작업이 실행되면 나중에 반복되지 않습니다. 실제 응용 프로그램에는 정기적으로 동일한 작업을 반복적으로 실행 해야하는 많은 시나리오가 있습니다. 두 가지 상황이 있습니다. 하나는 가끔씩 작업을 실행하는 것입니다. 다른 하나는 매일 (또는 주별, 월별 등) 특정 (또는 여러) 시점에서 작업을 수행하는 것입니다.
먼저 10 초마다 동일한 작업을 실행하는 예인 첫 번째 사례를 먼저 살펴 보겠습니다. 코드는 다음과 같습니다.
import java.text.simpledateformat; import java.util.date; import java.util.timer; import java.util.timertask; public class timerdemo {public static string getCurrentTime () {date date = new Date (); simpledateformat sdf = new simpledateformat ( "yyyy-mm-dd hh : mm : ss"); 반환 sdf.format (날짜); } public static void main (String [] args)은 InterruptedException {System.out.println ( "메인 시작 :"+getCurrentTime ()); STARTTIMER (); } public static void startTimer () {timertask task = new Timertask () {@override public void run () {system.out.println ( "task run :"+getCurrentTime ()); try {thread.sleep (1000*3); } catch (InterruptedException e) {e.printstacktrace (); }}}; 타이머 타이머 = 새로운 타이머 (); TIMER.SCEDULE (작업, 1000*5,1000*10); }} 위의 프로그램을 실행하면 출력 정보가 다음과 같습니다 (타이머가 중지되지 않고 작업이 반복되기 때문에 출력은 지속적으로 출력됩니다. 이전 출력 중 일부 만 여기에 복사됩니다).
메인 시작 : 2016-01-14 08:41:14
작업 실행 : 2016-01-14 08:41:19
작업 실행 : 2016-01-14 08:41:29
작업 실행 : 2016-01-14 08:41:39
작업 실행 : 2016-01-14 08:41:49
작업 실행 : 2016-01-14 08:42:00
작업 실행 : 2016-01-14 08:42:10
작업 실행 : 2016-01-14 08:42:20
작업 실행 : 2016-01-14 08:42:30
작업 실행 : 2016-01-14 08:42:40
위의 코드에서는 Timer.Schedule (작업, 1000*5,1000*10)을 호출합니다. 즉, 작업이 5 초 만에 지연되고 10 초마다 반복됩니다. 출력 정보의 인쇄 시간이 예상과 동일하다는 것을 관찰합니다. 또한,이 간격은 작업 시작 시간에 따라 계산된다는 것을 알 수 있습니다. 즉, 작업이 완료된 후 10 초를 기다리지 않아야합니다.
타이머 클래스에는 다음과 같이 이러한 기능을 구현하는 두 가지 방법이 있습니다.
공공 공간 일정 (Timertask 과제, 장기 지연, 장기) 공개 무효 일정 (Timertask 과제, 날짜 초기, 장기)
위의 코드를 사용하는 첫 번째 방법. 두 방법의 차이점은 첫 번째 실행 시간입니다. 첫 번째 방법은 일정 기간의 지정된 지연 (밀리 초) 후에 실행됩니다. 두 번째 방법은 지정된 시점에서 실행됩니다.
현재 다음 시나리오를 고려합니다. 작업의 실행 시간이 다음 대기 시간을 초과하면 어떻게됩니까? 코드를 통해 살펴 보겠습니다.
import java.text.simpledateformat; import java.util.date; import java.util.timer; import java.util.timertask; public class timerdemo {public static string getCurrentTime () {date date = new Date (); simpledateformat sdf = new simpledateformat ( "yyyy-mm-dd hh : mm : ss"); 반환 sdf.format (날짜); } public static void main (String [] args)은 InterruptedException {System.out.println ( "메인 시작 :"+getCurrentTime ()); STARTTIMER (); } public static void startTimer () {timertask task = new Timertask () {@override public void run () {system.out.println ( "task begin :"+getCurrentTime ()); try {thread.sleep (1000*10); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println ( "작업 종료 :"+getCurrentTime ()); }}; 타이머 타이머 = 새로운 타이머 (); TIMER.SCEDULE (작업, 1000*5,1000*5); }} 이전 코드와 비교하여 2 개의 코드 만 변경하고 인쇄를 수정했습니다. 하나는 실행 방법의 수면을 10 초로 변경하고 다른 하나는 작업의 실행주기를 5 초로 변경하는 것입니다. 다시 말해, 작업의 실행 시간은 작업의 반복 실행 간격을 초과합니다. 프로그램을 실행하면 이전 출력은 다음과 같습니다.
메인 시작 : 2016-01-14 09:03:51
작업 시작 : 2016-01-14 09:03:56
작업 종료 : 2016-01-14 09:04:06
작업 시작 : 2016-01-14 09:04:06
작업 종료 : 2016-01-14 09:04:16
작업 시작 : 2016-01-14 09:04:16
작업 종료 : 2016-01-14 09:04:26
작업 시작 : 2016-01-14 09:04:26
작업 종료 : 2016-01-14 09:04:36
작업 시작 : 2016-01-14 09:04:36
작업 종료 : 2016-01-14 09:04:46
작업 시작 : 2016-01-14 09:04:46
작업 종료 : 2016-01-14 09:04:56
각 작업이 실행되면 다음 작업이 즉시 실행된다는 것을 알 수 있습니다. 작업 시작부터 작업 완료까지의 시간이 작업 반복 사이의 간격을 초과 했으므로 실행이 반복됩니다.
5. 정기적으로 작업을 실행합니다 (고정 시점을 반복)
이러한 기능을 구현하고 매일 오전 1시에 정기적으로 작업을 수행하겠습니다.이 기능은이 작업에서 데이터 백업 및 데이터 통계와 같은 시간 소비 및 리소스 소비 작업을 완료하는 등 많은 시스템 에서이 기능을 갖습니다. 코드는 다음과 같습니다.
import java.text.simpledateformat; import java.util.calendar; import java.util.date; import java.util.timer; import java.util.timertask; public class timerdemo {public static string getCurrentTime () {Date Date = New Date (); simpledateformat sdf = new simpledateformat ( "yyyy-mm-dd hh : mm : ss"); 반환 sdf.format (날짜); } public static void main (String [] args)은 InterruptedException {System.out.println ( "메인 시작 :" + getCurrentTime ()); STARTTIMER (); } public static void startTimer () {timertask task = new Timertask () {@override public void run () {system.out.println ( "task begin :" + getCurrentTime ()); try {thread.sleep (1000 * 20); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println ( "작업 종료 :" + getCurrentTime ()); }}; 타이머 타이머 = 새로운 타이머 (); timer.schedule (task, buildtime (), 1000 * 60 * 60 * 24); } 개인 정적 날짜 빌드 타임 () {Calendar Calendar = Calendar.getInstance (); calendar.set (calendar.hour_of_day, 1); calendar.set (calendar.minute, 0); calendar.set (calendar.second, 0); 날짜 시간 = calendar.gettime (); if (time.pore (new date ())) {// 현재 시간이 오전 1시 이후에 1 일이 필요하며 그렇지 않으면 작업이 즉시 실행됩니다. // 많은 시스템은 종종 시스템이 시작될 때 즉시 작업을 실행해야하지만 매일 오전 1시에 작업을 수행해야합니다. 어떻게해야하나요? // 매우 간단합니다. 시스템이 통화를 초기화 할 때 작업을 별도로 실행합니다 (타이머가 필요하지 않으면 해당 작업을 실행하는 코드 일뿐) 시간 = AddDay (Time, 1); } 반환 시간; } 개인 정적 날짜 addday (날짜 날짜, int 일) {calendar startdt = calendar.getInstance (); startdt.settime (날짜); startdt.add (calendar.day_of_month, days); return startdt.gettime (); }}24 시간 간격으로 실행되기 때문에 출력의 관찰을 기다리는 것은 불가능합니다.
6. 요약
이 기사는 Java 타이머 클래스를 사용하여 시간이 지정된 작업을 수행하는 방법의 메커니즘을 소개합니다. 주의를 기울일 수있는 방법이 여전히 많다는 것을 알 수 있습니다. 이 기사에 소개 된 예제에서 각 타이머는 하나의 작업에만 해당됩니다.
이 기사에 소개 된 내용은 대부분의 응용 프로그램 시나리오를 충족 할 수 있지만 타이머에 대한 여러 작업을 포함하는 것과 같은 몇 가지 문제가 있습니까? 타이머가 취소 된 후 다시 작업을 추가 할 수 있습니까? 타이머 클래스에서 사용할 수있는 다른 방법은 무엇입니까? 이 질문들은 다음 블로그 게시물에 소개됩니다.
원본 링크 : http://www.cnblogs.com/51kata/p/5128745.html
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.