It is possible to run things asynchronly (in a other thread) and go back to synchronous (/ callbacks)?
I need this because I want to do database requests and one requests took 0.2 - 1.2ms.
My implementation in java:
And a example use of the queue:
I need this because I want to do database requests and one requests took 0.2 - 1.2ms.
My implementation in java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | package tv.rewinside.database.bukkit.util; import com.google.common.collect.Queues; import java.util.Queue; import java.util.logging.Level; import tv.rewinside.database.bukkit.DatabasePlugin; public class DatabaseQueue extends Thread { private final Queue<Runnable> runnables = Queues.newConcurrentLinkedQueue(); public DatabaseQueue() { super ( "Database Queue" ); this .setDaemon( true ); } public synchronized void addRunnable(Runnable runnable) { this .runnables.add(runnable); this .notify(); } private synchronized void blockCurrentThread() { try { while ( this .runnables.isEmpty()) { this .wait(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } public int getCount() { return this .runnables.size(); } @Override public void run() { while (! this .isInterrupted()) { this .blockCurrentThread(); while (! this .runnables.isEmpty()) { try { this .runnables.poll().run(); } catch (Exception ex) { DatabasePlugin.getInstance().getLogger().log(Level.WARNING, "Exception while execute database task" , ex); } } } } } public interface DatabaseCallback<T> { public void run(T result); } |
And a example use of the queue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | public void getPlayer( final String uuid, final DatabaseCallback<DatabasePlayer> callback) { DatabasePlayer dbPlayer = this .cachedPlayers.get(uuid); if (dbPlayer != null ) { callback.run(dbPlayer); return ; } // Load player -> Async this .plugin.getQueue().addRunnable( new Runnable() { @Override public void run() { DatabaseCache. this .syncCallbackCall(callback, DatabaseCache. this .loadPlayer(uuid)); } }); } private DatabasePlayer loadPlayer(String uuid) { DatabasePlayer dbPlayer = this .plugin.getConnection().getPlayer(uuid); if (dbPlayer == null ) return null ; this .cachedPlayers.put(uuid, dbPlayer); this .cachedPlayersFromName.put(dbPlayer.getLastName(), dbPlayer); return dbPlayer; } private <T> void syncCallbackCall( final DatabaseCallback<T> callback, final T arg) { if (Bukkit.isPrimaryThread()) { callback.run(arg); return ; } Bukkit.getScheduler().runTask( this .plugin, new Runnable() { @Override public void run() { callback.run(arg); } }); } |