Last active
May 19, 2021 08:55
-
-
Save NicoNekoDev/7c6d7bc7b48f5bb0dc82c049bcea406e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BlockingExample extends JavaPlugin implements Listener { | |
// enabling area | |
@Override | |
public void onEnable() { | |
this.getServer().getPluginManager().registerEvents(this, this); | |
this.startProcessing(); | |
} | |
// the producer area | |
@EventHandler | |
public void onBlockBreak(BlockBreakEvent event) { | |
try { | |
// this area will create an deadlock | |
event.getPlayer().sendMessage(this.getData("first message").get()); | |
event.getPlayer().sendMessage(this.getData("second message").get()); | |
event.getPlayer().sendMessage(this.getData("third message").get()); | |
// this all will wait to be completed, which will never happen | |
} catch (InterruptedException | ExecutionException ex) { | |
// mostly ignored | |
ex.printStackTrace(); | |
} | |
} | |
// the ticking area | |
public void startProcessing() { | |
Bukkit.getScheduler().runTaskTimer(this, () -> { | |
// process the data every tick | |
this.processData(); | |
// can be replaced with a lambda, i've keep it this way for readability sake | |
}, 1L, 1L); | |
} | |
// the process area | |
private final ConcurrentLinkedQueue<FutureTask<String>> processQueue = new ConcurrentLinkedQueue<>(); | |
private final ExecutorService executor = Executors.newSingleThreadExecutor(); | |
public FutureTask<String> getData(String arg) { | |
FutureTask<String> task = new FutureTask<>(() -> { | |
// this task will be used for some very-high intense work | |
// i've made it intentionally String to keep it simple | |
return arg + " [some intense task that was processed in parallel]"; | |
// can be replaced with a lambda, i've keep it this way for readability sake | |
}); | |
this.processQueue.offer(task); | |
return task; | |
} | |
public void processData() { | |
FutureTask<String> task = this.processQueue.poll(); | |
int total = 0; | |
while (task != null) { | |
if (total >= 2) { | |
// we allow only 2 task to be processed, to simulate a very high amount of data to be processed | |
// on a real application, there will be thousands of tasks to be processed | |
// this is used to limit the number of processed tasks | |
break; | |
// this will break the loop and processData() will need to be called again to restart the loop | |
} | |
total++; // increas the total tasks processed | |
this.executor.execute(task); | |
task = this.processQueue.poll(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment