2012-02-29 86 views
1

因此...Java TimerTask,取消時不會停止

我正在創建一個插件。

我有一個叫做基礎

在全球範圍內的基礎知識創建一個主類:

static Timer enterdungeon = new Timer(); 
static Timer finddungeon = new Timer(); 
static Timer lootdungeon = new Timer(); 

我也有一類名爲任務

的enterdungeon計時器是一個固定的時間週期,在使用時似乎按預期工作。 就像你的地下城計時器一樣。

如果觸發基礎事件,finddungeon定時器可能會中斷。

該事件確實觸發罰款 此事件的頂行是: finddungeon.cancel();

它啓動lootdungeon計時器後。

問題是finddungeon計時器不取消,繼續運行,下面是任務等級:

import java.util.TimerTask; 
import me.boduzapho.Basics.DoWarp.Returner; 
import org.bukkit.entity.Player; 

public class task extends TimerTask 
{ 
private final Player _player; 
private final int ticks; 
private int cnt = 0; 
private final int _sec; 
private final String _message; 

public task(Player player, int sec, String message) 
{ 
    this._player = player; 
    this._sec = sec; 
    this._message = message; 
    this.ticks = sec; 
} 

private void timetoloot(Player p) 
{ 

    p.sendMessage("SUCCESS! Nice Job, Enjoy the loot!"); 
    Returner loc1 = DoWarp.getwarp("launch", Basics.warps, Basics.wx,Basics.wy, Basics.wz, p); 
    DoWarp.warpme(loc1.x, loc1.y, loc1.z, p, false, Basics.plugin); 

} 

private void failedwhiteblock(Player p) 
{ 
    p.sendMessage("FAIL! You did not find the white block. Sending you back. TRY AGAIN!"); 
    Returner loc1 = DoWarp.getwarp("launch", Basics.warps, Basics.wx, Basics.wy, Basics.wz, p); 
    DoWarp.warpme(loc1.x, loc1.y, loc1.z, p, false, Basics.plugin); 

} 

private void enterdungeon(Player p) 
{ 
    Basics.Stage.setLine(3, "Off you Go!"); 
    Basics.Stage.update(); 
    Basics.Stage.setLine(0, ""); 
    Basics.Stage.setLine(1, ""); 
    Basics.Stage.setLine(2, ""); 
    Basics.Stage.setLine(3, ""); 
    Basics.Stage.update(); 

    Basics.cDoClear(p); 
    Basics.cDoSpawners(p); 
    Basics.cDoRed(p); 
    Returner loc1 = DoWarp.getwarp("dstart", Basics.warps, Basics.wx, Basics.wy, Basics.wz, p); 
    DoWarp.warpme(loc1.x, loc1.y, loc1.z, p, false, Basics.plugin); 
    Basics.DungeonPlayer = p; 
    p.sendMessage("Welcome to the Dungeon, you have 1 minuite to locate and click the white block."); 
    p.sendMessage("If you fail you will be returned to spawn. If you find it the treasures will be revieled"); 
    p.sendMessage("and the monsters banished for 1 min so you can loot the chests! After which you will"); 
    p.sendMessage("Be warped back to spawn with your Loot!"); 
    Basics.finddungeon.schedule(new task(_player, 30, "Time left to find the WHITE block :"), 0, 1000); 
    Basics.enterdungeon.cancel(); 
} 

@Override 
public void run() 
{ 
    while (cnt < ticks) 
    { 
     try 
     { 
      Thread.sleep(1 * 1000); 
      _player.sendMessage(_message + " " + Integer.toString(_sec - cnt)); 
      ++cnt; 
     } 
     catch (InterruptedException e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
    _player.sendMessage("Done!"); 
    if (_message == "Time left:") 
    { 
     enterdungeon(_player); 
    } 

    if (_message == "Time left to find the WHITE block :") 
    { 
     failedwhiteblock(_player); 
    } 

    if (_message == "Time left to LOOT:") 
    { 
     timetoloot(_player); 
    } 

    // 

    return; 

} 
} 

這就是所謂的基礎(主類)的功能是應該取消finddungeon計時器。

// white block in dungeon 
     if (DungeonPlayer == player) 
     { 
      if ((block != null) && (block.getType() == Material.WOOL)) 
      { 
       player.sendMessage("Canceling finddungeon from Basics"); 
       finddungeon.cancel(); 
       cDoClear(player); 
       cDoChests(player); 

       player.sendMessage("Congradulations! Time to Loot your rewards for finding the White Block!"); 
       Timer lootdungeon = new Timer(); 
       lootdungeon.schedule(new task(player, 10, "Time left to LOOT:"), 0, 1000); 

       return; 
       // *** 
      } 
     } 

任何人都可以對此有所瞭解嗎?

+0

我試圖全局聲明一個布爾變量,它在定時器的運行事件中被檢查。默認情況下,我將其設置爲false,並指示時間繼續。當白塊事件被觸發時,我將它設置爲true,以指示運行事件調用cancel(按照來自java的指令,作爲殺死定時器的傻瓜式方法)。這也是行不通的。通過反射「聊天」,我可以看到定時器布爾變量從false變爲true,並且cancel();被叫,但計時器只是繼續前進。 – Boduzapho 2012-02-29 10:33:25

回答

1

原因TimerTask.cancel不對活動任務執行任何操作,它只是清除調度程序。你必須重寫取消方法,或者只是以此爲出發點:

class MyTimerTask extends TimerTask { 
    private volatile Thread thread; 

    @Override 
    public void run() { 
     thread = Thread.currentThread(); 
     //do your task and keep your eye on InterruptedException when doing Sleeps, Waits 
     //also check Thread.interrupted() 
    } 

    public boolean cancel() { 
     Thread thread = this.thread; 
     if (thread != null) { 
      thread.interrupt(); 
     } 
     return super.cancel(); 
    } 
}