如何 运行 方法与可完成的未来异步
How to run methods asynchronously with completable future
我正在 运行 设置一个 Minecraft
服务器,我正在创建一个插件,当玩家执行某个命令时。它获取 'coins' 他们在 sql
数据库中的数量。然而,我 运行 遇到麻烦使用 CompletableFuture
到 运行 我的 SQL 异步方法。我的 CoinUsable
class 一直阻塞,我的 main 和 sql class 也是。我对异步编程很陌生。
我只需要找出一种方法 运行 我的 CoinUsable
和 SQLManager
class 中的方法是异步的。
我的主要class玩家执行命令的地方。
CompletableFuture<Integer> cf = CoinUsable.getPlayerCoins(player);
cf.thenAcceptAsync((value) -> {
player.sendMessage(ChatColor.GRAY + "You own " + ChatColor.GOLD + value + ChatColor.GRAY + " coins");
});
我的CoinUsable/Managerclass
public CompletableFuture<Integer> getPlayerCoins(Player p) {
return SQL.getPlayerBits(p);
}
public CompletableFuture<Void> addPlayerBits(Player p, int bitAmount) {
SQL.addBits(p, bitAmount);
return null;
}
public CompletableFuture<Void> removePlayerBits(Player p, int bitAmount) {
SQL.removeBits(p, bitAmount);
return null;
}
我的SQL经理class
public CompletableFuture<Integer> getPlayerBits(Player p) {
String queryStr = "SELECT Coins FROM PlayerData WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement st = conn.prepareStatement(queryStr);
st.setString(1, p.getUniqueId().toString());
ResultSet rs = st.executeQuery();
rs.next();
Integer amount = (Integer) rs.getInt("Coins");
conn.close();
return CompletableFuture.completedFuture(amount);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public CompletableFuture<Void> addBits(Player p, int bitAmount) {
String queryStr = "UPDATE PlayerData SET Coins = Coins + ? WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement ps = conn.prepareStatement(queryStr);
ps.setInt(1, bitAmount);
ps.setString(2, p.getUniqueId().toString());
ps.executeUpdate();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture(null);
}
public CompletableFuture<Void> removeBits(Player p, int bitAmount) {
String queryStr = "UPDATE PlayerData SET Coins = Coins - ? WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement ps = conn.prepareStatement(queryStr);
ps.setInt(1, bitAmount);
ps.setString(2, p.getUniqueId().toString());
ps.executeUpdate();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture(null);
}
}
我的主 class 正在阻塞,导致整个服务器延迟。还有我的 CoinUsable class 它也阻塞了,这意味着玩家必须等待另一个玩家请求通过才能发送他的请求。
使用CompletableFuture<Void> runAsync(Runnable runnable)
Returns a new CompletableFuture that is asynchronously completed by a task running in the ForkJoinPool.commonPool() after it runs the given action.
和CompletableFuture<U> supplyAsync(Supplier<U> supplier)
Returns a new CompletableFuture that is asynchronously completed by a task running in the ForkJoinPool.commonPool() with the value obtained by calling the given Supplier.
对于异步执行使用supplyAsync
和runAsync
,你使用CompletableFuture
的方式是错误的
CoinUsable/Manager class : 使用 supplyAsync
和 runAsync
方法调用 SQLManager
class 方法,以便 getPlayerBits
、addBits
和 removeBits
将异步执行
public CompletableFuture<Integer> getPlayerCoins(Player p) {
return CompletableFuture.supplyAsync(()->SQL.getPlayerBits(p));
}
public CompletableFuture<Void> addPlayerBits(Player p, int bitAmount) {
return CompletableFuture.runAsync(()->SQL.addBits(p, bitAmount));
}
public CompletableFuture<Void> removePlayerBits(Player p, int bitAmount) {
return CompletableFuture.runAsync(()->SQL.removeBits(p, bitAmount));
}
我的 SQLManager class : 在 SQLManager
class 中只保持方法与各自 return 类型的正常
public Integer getPlayerBits(Player p) {
String queryStr = "SELECT Coins FROM PlayerData WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement st = conn.prepareStatement(queryStr);
st.setString(1, p.getUniqueId().toString());
ResultSet rs = st.executeQuery();
rs.next();
Integer amount = (Integer) rs.getInt("Coins");
conn.close();
return amount;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public void addBits(Player p, int bitAmount) {
String queryStr = "UPDATE PlayerData SET Coins = Coins + ? WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement ps = conn.prepareStatement(queryStr);
ps.setInt(1, bitAmount);
ps.setString(2, p.getUniqueId().toString());
ps.executeUpdate();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void removeBits(Player p, int bitAmount) {
String queryStr = "UPDATE PlayerData SET Coins = Coins - ? WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement ps = conn.prepareStatement(queryStr);
ps.setInt(1, bitAmount);
ps.setString(2, p.getUniqueId().toString());
ps.executeUpdate();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
我正在 运行 设置一个 Minecraft
服务器,我正在创建一个插件,当玩家执行某个命令时。它获取 'coins' 他们在 sql
数据库中的数量。然而,我 运行 遇到麻烦使用 CompletableFuture
到 运行 我的 SQL 异步方法。我的 CoinUsable
class 一直阻塞,我的 main 和 sql class 也是。我对异步编程很陌生。
我只需要找出一种方法 运行 我的 CoinUsable
和 SQLManager
class 中的方法是异步的。
我的主要class玩家执行命令的地方。
CompletableFuture<Integer> cf = CoinUsable.getPlayerCoins(player);
cf.thenAcceptAsync((value) -> {
player.sendMessage(ChatColor.GRAY + "You own " + ChatColor.GOLD + value + ChatColor.GRAY + " coins");
});
我的CoinUsable/Managerclass
public CompletableFuture<Integer> getPlayerCoins(Player p) {
return SQL.getPlayerBits(p);
}
public CompletableFuture<Void> addPlayerBits(Player p, int bitAmount) {
SQL.addBits(p, bitAmount);
return null;
}
public CompletableFuture<Void> removePlayerBits(Player p, int bitAmount) {
SQL.removeBits(p, bitAmount);
return null;
}
我的SQL经理class
public CompletableFuture<Integer> getPlayerBits(Player p) {
String queryStr = "SELECT Coins FROM PlayerData WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement st = conn.prepareStatement(queryStr);
st.setString(1, p.getUniqueId().toString());
ResultSet rs = st.executeQuery();
rs.next();
Integer amount = (Integer) rs.getInt("Coins");
conn.close();
return CompletableFuture.completedFuture(amount);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public CompletableFuture<Void> addBits(Player p, int bitAmount) {
String queryStr = "UPDATE PlayerData SET Coins = Coins + ? WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement ps = conn.prepareStatement(queryStr);
ps.setInt(1, bitAmount);
ps.setString(2, p.getUniqueId().toString());
ps.executeUpdate();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture(null);
}
public CompletableFuture<Void> removeBits(Player p, int bitAmount) {
String queryStr = "UPDATE PlayerData SET Coins = Coins - ? WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement ps = conn.prepareStatement(queryStr);
ps.setInt(1, bitAmount);
ps.setString(2, p.getUniqueId().toString());
ps.executeUpdate();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture(null);
}
}
我的主 class 正在阻塞,导致整个服务器延迟。还有我的 CoinUsable class 它也阻塞了,这意味着玩家必须等待另一个玩家请求通过才能发送他的请求。
使用CompletableFuture<Void> runAsync(Runnable runnable)
Returns a new CompletableFuture that is asynchronously completed by a task running in the ForkJoinPool.commonPool() after it runs the given action.
和CompletableFuture<U> supplyAsync(Supplier<U> supplier)
Returns a new CompletableFuture that is asynchronously completed by a task running in the ForkJoinPool.commonPool() with the value obtained by calling the given Supplier.
对于异步执行使用supplyAsync
和runAsync
,你使用CompletableFuture
的方式是错误的
CoinUsable/Manager class : 使用 supplyAsync
和 runAsync
方法调用 SQLManager
class 方法,以便 getPlayerBits
、addBits
和 removeBits
将异步执行
public CompletableFuture<Integer> getPlayerCoins(Player p) {
return CompletableFuture.supplyAsync(()->SQL.getPlayerBits(p));
}
public CompletableFuture<Void> addPlayerBits(Player p, int bitAmount) {
return CompletableFuture.runAsync(()->SQL.addBits(p, bitAmount));
}
public CompletableFuture<Void> removePlayerBits(Player p, int bitAmount) {
return CompletableFuture.runAsync(()->SQL.removeBits(p, bitAmount));
}
我的 SQLManager class : 在 SQLManager
class 中只保持方法与各自 return 类型的正常
public Integer getPlayerBits(Player p) {
String queryStr = "SELECT Coins FROM PlayerData WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement st = conn.prepareStatement(queryStr);
st.setString(1, p.getUniqueId().toString());
ResultSet rs = st.executeQuery();
rs.next();
Integer amount = (Integer) rs.getInt("Coins");
conn.close();
return amount;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public void addBits(Player p, int bitAmount) {
String queryStr = "UPDATE PlayerData SET Coins = Coins + ? WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement ps = conn.prepareStatement(queryStr);
ps.setInt(1, bitAmount);
ps.setString(2, p.getUniqueId().toString());
ps.executeUpdate();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void removeBits(Player p, int bitAmount) {
String queryStr = "UPDATE PlayerData SET Coins = Coins - ? WHERE PlayerUID=?";
try {
Connection conn = getConn();
PreparedStatement ps = conn.prepareStatement(queryStr);
ps.setInt(1, bitAmount);
ps.setString(2, p.getUniqueId().toString());
ps.executeUpdate();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}