0

我有一个实时程序,我需要执行一个名为“execTask(Packet task)”的方法,只需要在某个 System.currentTimeMillis() 调用它。有没有办法做到这一点?

4

3 回答 3

2

ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit)

于 2012-10-11T19:02:18.780 回答
0

比你想要的多一点,但相当笼统(一旦有人清理了特定的东西):

事件列表.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();
    }
}

事件对象.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;
    }
}

计时员.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;
        }
    }

}
于 2012-10-11T19:09:35.143 回答
0

查看Quartz调度程序。我假设您是在 Java 中执行此操作的?

于 2012-10-11T18:56:05.883 回答