2012-10-11 60 views
0

我有一個實時程序,我需要執行一個名爲「execTask(數據包任務)」的方法,只需要在某個System.currentTimeMillis()中調用它。有沒有辦法做到這一點?如何使用System.currentTimeMillis()在某個時間執行一個方法?

+1

要注意的是毫秒級和時鐘漂移特定於平臺的問題。請參閱http://stackoverflow.com/a/2905082/7507和https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks – noahlz

回答

0

檢出Quartz調度程序。我假設你在Java中這樣做?

+0

JCreator 5.0 LE –

0

多一點你可能想要的,但相當普遍的(一旦有人清理出來的具體的東西):

EventList.java

/** 
* 
*/ 
package com.jodatosa.auction.timekeeper; 

import java.util.concurrent.DelayQueue; 

/** 
* @author db2admin 
* 
*/ 
public class EventList { 

    public static final int NO_EVENT = 0; 
    public static final int SWITCH_ITEM_TO_POSTED = 1; 
    public static final int SWITCH_ITEM_TO_CLOSED = 2; 
    public static final int UNLOCK_REGISTERED_USER = 3; 

    private DelayQueue<EventObject> eventList; 

    public EventList() { 
     eventList = new DelayQueue<EventObject>(); 
    } 

    public void add(int eventType, long eventTime, int id) { 
     eventList.put(new EventObject(eventType, eventTime, id)); 
    } 

    public EventObject waitForNext() throws InterruptedException { 
     return eventList.take(); 
    } 

    public int size() { 
     return eventList.size(); 
    } 

    public EventObject peek() { 
     return eventList.peek(); 
    } 
} 

EventObject.java

package com.jodatosa.auction.timekeeper; 

import java.util.concurrent.Delayed; 
import java.util.concurrent.TimeUnit; 

import com.jodatosa.auction.auditing.Trace; 

public class EventObject implements Delayed { 
    int eventType; 
    long eventTime; 
    int id; 

    EventObject(int eventType, long eventTime, int id) { 
     this.eventType = eventType; 
     this.eventTime = eventTime; 
     this.id = id; 
    } 

    public long getDelay(TimeUnit unit) { 
     long delay = unit.convert(eventTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); 
     if (unit == TimeUnit.MILLISECONDS) { 
      Trace.message("EventObject.getDelay time unit = MILLISECONDS"); 
     } 
     else if (unit == TimeUnit.MICROSECONDS) { 
      Trace.message("EventObject.getDelay time unit = MICROSECONDS"); 
     } 
     else if (unit == TimeUnit.NANOSECONDS) { 
      Trace.message("EventObject.getDelay time unit = NANOSECONDS"); 
     } 
     Trace.message("EventObject.getDelay returning " + delay); 
     return delay; 
    } 

    public int compareTo(Delayed o) { 
     EventObject comparand = (EventObject) o; 
     if (this.eventTime < comparand.eventTime) { 
      return -1; 
     } 
     else if (this.eventTime > comparand.eventTime) { 
      return 1; 
     } 
     return 0; 
    } 
} 

Timekeeper.java

/** 
* 
*/ 
package com.jodatosa.auction.timekeeper; 

import java.sql.SQLException; 

import com.jodatosa.auction.auditing.Trace; 
import com.jodatosa.auction.controller.AuctionControl; 
import com.jodatosa.auction.datastore.jdbc.TableConnection; 
import com.jodatosa.auction.model.Item; 
import com.jodatosa.auction.model.User; 
import com.jodatosa.auction.util.AuctionProperties; 

/** 
* @author db2admin 
* 
*/ 
public class Timekeeper { 

    private static EventList eventList; 

    public Timekeeper() { 
     // TODO 
    } 

    public static void initializeEventList() throws SQLException { 

     eventList = new EventList(); 

     long currentTime = System.currentTimeMillis(); 

     // Scan Users for locked Users and extract the time locked 
     User user = User.findByStatus(User.ACCOUNT_DISABLED_FOR_LOGIN); 
     if (user != null) { 
      long currentTimePlus2 = System.currentTimeMillis() - AuctionProperties.getTimeForLockedUserToUnlock(); 
      do { 

       // Compare time locked + 2 days to current time 
       if (user.getTime_locked_for_failed_logins() < currentTimePlus2) { 
        Trace.message("Timekeeper.initializeEventList: Unlocking user " + user.getUser_name() + ", locked at time " + user.getTime_locked_for_failed_logins()); 
        // Immediately unlock those where time has expired. 
        AuctionControl.unlockRegisteredUser(user.getUser_id()); 
       } 
       else { 
        // For those not expired, enter an event into the event list. 
        int eventType = EventList.UNLOCK_REGISTERED_USER; 
        long eventTime = user.getTime_locked_for_failed_logins() + AuctionProperties.getTimeForLockedUserToUnlock(); 
        int userId = user.getUser_id(); 
        Trace.message("Timekeeper.initializeEventList: Adding event type " + eventType + " for user " + user.getUser_name() + " at time " + eventTime); 
        eventList.add(eventType, eventTime, userId); 
       } 

      } while (user.next()); 
     } 

     // Scan Items. Extract item status, time to post, and time to close. 
     // For items not yet posted, check time to post and either set status to posted or add to event list. 
     // For posted items not yet closed, check time to close and process similarly. 
     Item item = Item.getAll(); 

     if (item != null) { 
      boolean more = true; 
      do { 
       int itemId = item.getItem_id(); 
       int status = item.getStatus(); 
       Trace.message("Timekeeper.initializeEventList: Examining item #" + itemId + " with status " + status); 
       int oldStatus = status; 
       long eventTime = 0; 
       int eventType = EventList.NO_EVENT; 
       if (status == Item.STATUS_NOT_POSTED) { 
        long timeToPost = item.getTime_to_post(); 
        if (timeToPost < currentTime) { 
         // Switch status to posted 
         status = Item.STATUS_POSTED; 
        } 
        else { 
         // Add item to event list 
         eventTime = timeToPost; 
         eventType = EventList.SWITCH_ITEM_TO_POSTED; 
        } 
       } 
       if (status == Item.STATUS_POSTED) { 
        long timeToClose = item.getTime_to_close(); 
        if (timeToClose < currentTime) { 
         // Switch status to closed 
         status = Item.STATUS_CLOSED; 
        } 
        else { 
         // Add item to event list 
         eventTime = timeToClose; 
         eventType = EventList.SWITCH_ITEM_TO_CLOSED; 
        } 
       } 

       // If item status changed, update item 
       if (status != oldStatus) { 
        Trace.message("Timekeeper.initializeEventList: Changing item #" + itemId + " status " + oldStatus + " to " + status); 
        Item updateItem = Item.getByItemIdForUpdate(itemId); 
        if (updateItem == null) { 
         Trace.error("Could not find item #" + itemId + " to update"); 
        } 
        else { 
         updateItem.setStatus(status); 
         updateItem.update(); 
         TableConnection.commit(); 
        } 
       } 

       // If event type set, register new event to occur. 
       if (eventType != EventList.NO_EVENT) { 
        Trace.message("Timekeeper.initializeEventList: Adding event type " + eventType + " for item #" + itemId + " at time " + eventTime); 
        eventList.add(eventType, eventTime, itemId); 
       } 

       // Advance to next entry 
       more = item.next(); 
      } while(more); 
     } 


     // TODO -- Dutch auction 
    } 

    public static Thread startTimerThread() { 
     TimerThread timerThread = new TimerThread(eventList); 
     timerThread.setName("AuctionTimerThread"); 
     timerThread.setDaemon(true); 
     timerThread.start(); 
     Trace.message("Timekeeper.startTimerThread completed"); 
     return timerThread; 
    } 

    public static void endTimerThread(Thread timerThread) { 
     timerThread.interrupt(); 
    } 

    public static void addAuctionStart(int auctionId, long postTime) { 
     eventList.add(EventList.SWITCH_ITEM_TO_POSTED, postTime, auctionId); 
    } 

    public static void addAuctionClose(int auctionId, long closeTime) { 
     eventList.add(EventList.SWITCH_ITEM_TO_CLOSED, closeTime, auctionId); 
    } 

    public static void addRegisteredUserLocked(int userId, long lockTime) { 
     eventList.add(EventList.UNLOCK_REGISTERED_USER, lockTime + AuctionProperties.getTimeForLockedUserToUnlock(), userId); 
    } 
} 

TimerThread.java

/** 
* 
*/ 
package com.jodatosa.auction.timekeeper; 

import java.sql.SQLException; 

import com.jodatosa.auction.auditing.Trace; 
import com.jodatosa.auction.controller.AuctionControl; 

/** 
* @author db2admin 
* 
*/ 
public class TimerThread extends Thread implements Runnable { 

    private EventList eventList; 

    public TimerThread(EventList eventList) { 
     this.eventList = eventList; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Runnable#run() 
    */ 
    public void run() { 
     Trace.message("TimerThread.run starting"); 
     try { 
      while(true) { 
       Trace.message("TimerThread.run: EventList size = " + eventList.size()); 
       EventObject peekObject = eventList.peek(); 
       if (peekObject == null) { 
        Trace.message("TimerThread.run: EventList peek = null"); 
       } 
       else { 
        Trace.message("TimerThread.run: EventList peek = " + peekObject.eventType + ", " + peekObject.eventTime + ", " + peekObject.id); 
       } 
       EventObject eventObject = eventList.waitForNext(); 
       Trace.message("TimerThread.run: EventObject type " + eventObject.eventType + " being processed"); 
       if (eventObject.eventType == EventList.SWITCH_ITEM_TO_POSTED) { 
        Trace.message("TimerThread: Switch Item to POSTED"); 
        try { 
         AuctionControl.startAuction(eventObject.id); 
        } 
        catch (SQLException ex) { 
         Trace.error("TimerThread: AuctionControl.startAuction failed with exception " + ex.toString()); 
         Trace.exception(ex); 
        } 
       } 
       else if (eventObject.eventType == EventList.SWITCH_ITEM_TO_CLOSED) { 
        Trace.message("TimerThread: Switch Item to CLOSED"); 
        try { 
         AuctionControl.endAuction(eventObject.id); 
        } 
        catch (SQLException ex) { 
         Trace.error("TimerThread: AuctionControl.endAuction failed with exception " + ex.toString()); 
         Trace.exception(ex); 
        } 
       } 
       else if (eventObject.eventType == EventList.UNLOCK_REGISTERED_USER) { 
        Trace.message("TimerThread: Unlock registered user"); 
        try { 
         AuctionControl.unlockRegisteredUser(eventObject.id); 
        } 
        catch (SQLException ex) { 
         Trace.error("TimerThread: AuctionControl.unlockRegisteredUser failed with exception " + ex.toString()); 
         Trace.exception(ex); 
        } 
       } 
       else { 
        Trace.error("TimerThread: Unrecognized event type " + eventObject.eventType); 
       } 
      } 
     } 
     catch (InterruptedException ex) { 
      Trace.message("TimerThread interrupted"); 
      return; 
     } 
    } 

} 
相關問題