سؤال

ولقد نفذت نظام رمزي الذي يعين عدد ثابت من الرموز. كل رمز في مهمة يبدأ حتى الموقت التي تنتهي بعد عدد قليل من دقيقة ومسح أن فتحة رمزية لإعادة استخدامها. إذا كان المستخدم بالتحقق من صحة رمز قبل انتهاء توقيت يفترض الموقت إلى إلغاء وإعادة مع فترة صلاحية رمزية أخرى. ويبدو لي أن تكون قادرة على إلغاء المؤقت من خارج موضوع مؤقت، وهذا هو السلوك المتوقع. قصاصات تابع:

/**
 * Fills one of the available slots with a new session key
 * @param sessionKey
 * @return true on slot fill success - false on fail
 */
public boolean fillSlot(String sessionKey)
{
    if(count<MAXCOUNT)
    {
        //Add key to slot
        slots.add(sessionKey);
        //Up the key count
        upCount();
        //Set up expiry timer
        Timer timer = new Timer();
        timer.schedule(new ExpiringTokentask(timer,sessionKey), EXPIRY_TIME);
        timers.put(sessionKey, timer);
        return true;
    }
    return false;
}

    /**
 * Check if a given key is stored in the slots
 * reset timer every time key is checked
 * @param sessionKey
 * @return true on key found false on not found
 */
public boolean checkSlot(String sessionKey)
{
    //TODO: More efficient key search and storage for larger user sets
    //TODO: Upgrade from memory array to h2 embedded DB
    for(int i=0;i<slots.size();i++)
    {
        if(sessionKey.equals(slots.get(i)))
        {
            //Reset timer
            Timer timer = timers.get(sessionKey);
            //Can't seem to do this
            // timer.cancel();
            timer.schedule(new ExpiringTokentask(timer,sessionKey), EXPIRY_TIME);
            //Return token validation
            return true;
        }
    }

    return false;
}


private class ExpiringTokentask extends TimerTask
{
    private Timer timer;
    private String expireToken;

    public ExpiringTokentask(Timer timer, String sessionKey)
    {
        this.timer = timer;
        this.expireToken = sessionKey;
        System.out.println(sessionKey);
    }

    public void run() {
        System.out.format("Time's up!%n");
        clearSlot(expireToken);
        timer.cancel(); //Terminate the timer thread
    }
}
هل كانت مفيدة؟

المحلول

وكما قيل، يمكنك إلغاء TimerTask الذي تم تقديمه إلى الموقت بدلا من إلغاء جهاز ضبط الوقت، وبهذه الطريقة لم يكن لديك أي وقت مضى لتصل الجديدة المزيد من توقيت.

ما تقومون به:

timer.cancel();
timer.schedule(...);

وسوف يلقي IllegalStateExceptions منذ كنت CAN NOT جدولة المهام الجديدة على جهاز توقيت إلغاء.

وهكذا بدلا من القيام: timer.cancel () لديهم الخريطة يكون تعيين من مفاتيح جلسة لTimerTasks وتلغي TimerTask بدلا من الموقت. بهذه الطريقة لم يكن لديك لتصل جديدة توقيت الجديدة، وسوف الموقت الخاص بك يعمل كما هو متوقع بعد إلغاء واحد أو أكثر من مهامها. عليك أيضا أن تكون قادرة على استخدام جهاز توقيت واحد لمعالجة العديد من الدورات. الآن كنت ترغب بجعل الموقت واحدة، وبالتالي موضوع واحد في كل دورة.

وعلى صعيد آخر، يجب عدم استخدام java.util.Timer. ماذا يحدث إذا كان أي من TimerTasks بك يطرح استثناء؟ سيقتلون الموقت وأبدا تشغيل مرة أخرى! ما إذا كان أحد TimerTasks الخاص بك هو بطيء أو كتل لأجل غير مسمى؟ فإن أي TimerTasks البعض على أن توقيت لن تكون قادرة على تنفيذه. النظر في استخدام ScheduledThreadPoolExecutor بدلا من ذلك. أنا متأكد من أن java.util.Timer سيتم إهمال من قبل الافراج جافا المقبل.

نصائح أخرى

وأعتقد أنه يمكنك استخدام كائن واحد توقيت واحد، وخلق أكبر عدد ممكن TimerTasks بدلا من خلق العديد من أجهزة ضبط الوقت. مؤقتات مكلفة، وذلك باستخدام واحد أو اثنين من توقيت لتطبيق كامل ينبغي أن يكون كافيا. أيضا، كنت إلغاء مؤقت وليس TimerTask محاولة إلغاء TimerTask

إذا الموقت هو غير فارغة، يجب أن تكون قادرا على استدعاء cancel() من أي موضوع. وهناك طريقة أفضل للقيام بذلك هو استخدام ScheduledExecutorService، والحصول على Future لكل مهمة المقدمة. مع المستقبل، يمكنك إلغائها، أو تحقق النتيجة.

وبعد السطر حيث حاولت وإلغاء المؤقت، يجب إنشاء واحدة جديدة قبل استدعاء الأسلوب الموعد المحدد.

if(sessionKey.equals(slots.get(i)))
{
  //Reset timer
  Timer timer = timers.get(sessionKey);
  //Can't seem to do this
  timer.cancel();
  timer = new Timer();
  timer.schedule(new ExpiringTokentask(timer,sessionKey), EXPIRY_TIME);
  //Return token validation
  return true;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top