我的MC插件有问题,我需要一个等待条件满足的无限循环。但它创建了一个无限循环,但变量已经改变。这是代码:
boolean bState;
public boolean GetState(){
return bState;
}
public void SetState(boolean bState) {
this.bState = bState;
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) throws InterruptedException {
Player player = event.getPlayer();
if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && event.getClickedBlock().getType() == Material.CHEST && event.getItem().getType() == Material.DIAMOND_SWORD) {
Chest chest = (Chest) event.getClickedBlock().getState();
event.setCancelled(true);
Inventory inv = chest.getInventory();
inv.getContents();
Inventory sinv = Bukkit.createInventory(player, chest.getInventory().getSize());
sinv.setContents(inv.getContents());
SetState(false);
player.openInventory(sinv);
while(GetState() == false){
getLogger().info("Ok");
}
//Some other things to do
}
}
@EventHandler
public void onPlayerCloseInv(InventoryCloseEvent event) {
Player player = (Player) event.getPlayer();
SetState(true);
}
我确信100%在onPlayerInteract之后触发了事件onPlayerCloseInv。谁能帮我 ? 谢谢:D
编辑: 我的新代码onPlayerCloseInv没有启动任何人有想法吗?
答案 0 :(得分:2)
使用bukkit,你只有一个主线程的原则。
因为这个线程一次只能做一件事,所以你不能使用自旋锁来等待条件,因为自旋锁基本上会让线程忙。
setState
虽然这是最简单的方法,但使用遗嘱,您将失去对本地变量的跟踪。
public void SetState(boolean bState) {
if(this.bState == false && bState == true) {
//Some other things to do
getLogger().info('Inventory closed');
}
this.bState = bState;
}
虽然这种方法会受到新lamba实例的惩罚以及稍微混淆的堆栈跟踪,但是使用它可以访问所有本地(隐含的)最终变量。
Runnable closeTask = null;
public void SetState(boolean bState) {
if(this.bState == false && bState == true ) {
if(closeTask != null) {
closeTask.run();
closeTask = null;
}
}
this.bState = bState;
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) throws InterruptedException {
Player player = event.getPlayer();
if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && event.getClickedBlock().getType() == Material.CHEST && event.getItem().getType() == Material.DIAMOND_SWORD) {
...
player.openInventory(sinv);
closeTask = () => {
//Some other things to do
getLogger().info('Inventory closed');
};
}
}