Skip to content

Instantly share code, notes, and snippets.

@NicoNekoDev
Last active May 19, 2021 08:55
Show Gist options
  • Save NicoNekoDev/7c6d7bc7b48f5bb0dc82c049bcea406e to your computer and use it in GitHub Desktop.
Save NicoNekoDev/7c6d7bc7b48f5bb0dc82c049bcea406e to your computer and use it in GitHub Desktop.
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