feat: 使用 ConcurrentHashMap 优化运行速度

This commit is contained in:
2024-04-05 10:31:42 +08:00
parent a093d411ec
commit 250bd94e39
3 changed files with 45 additions and 74 deletions

View File

@@ -5,7 +5,7 @@ plugins {
} }
group 'cn.hamster3' group 'cn.hamster3'
version '2.2.0' version '2.2.1'
repositories { repositories {
maven { maven {

View File

@@ -10,21 +10,19 @@ import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.HashSet; import java.util.concurrent.ConcurrentHashMap;
import java.util.Set;
import java.util.UUID;
import static cn.hamster3.currency.HamsterCurrency.getLogUtils; import static cn.hamster3.currency.HamsterCurrency.getLogUtils;
public class FileDataManager implements IDataManager { public class FileDataManager implements IDataManager {
private final HamsterCurrency plugin; private final HamsterCurrency plugin;
private final HashSet<PlayerData> playerData; private final Map<UUID, PlayerData> playerData;
private final HashSet<CurrencyType> currencyTypes; private final HashSet<CurrencyType> currencyTypes;
public FileDataManager(HamsterCurrency plugin) { public FileDataManager(HamsterCurrency plugin) {
this.plugin = plugin; this.plugin = plugin;
playerData = new HashSet<>(); playerData = new ConcurrentHashMap<>();
currencyTypes = new HashSet<>(); currencyTypes = new HashSet<>();
} }
@@ -42,7 +40,7 @@ public class FileDataManager implements IDataManager {
for (File file : files) { for (File file : files) {
try { try {
PlayerData data = new PlayerData(YamlConfiguration.loadConfiguration(file)); PlayerData data = new PlayerData(YamlConfiguration.loadConfiguration(file));
playerData.add(data); playerData.put(data.getUuid(), data);
} catch (Exception e) { } catch (Exception e) {
getLogUtils().error(e, "加载玩家存档文件 %s 时出现了一个异常!", file.getName()); getLogUtils().error(e, "加载玩家存档文件 %s 时出现了一个异常!", file.getName());
} }
@@ -54,7 +52,7 @@ public class FileDataManager implements IDataManager {
@Override @Override
public void onDisable() { public void onDisable() {
File dataFolder = new File(plugin.getDataFolder(), "PlayerData"); File dataFolder = new File(plugin.getDataFolder(), "PlayerData");
for (PlayerData data : playerData) { for (PlayerData data : playerData.values()) {
File dataFile = new File(dataFolder, data.getUuid().toString() + ".yml"); File dataFile = new File(dataFolder, data.getUuid().toString() + ".yml");
try { try {
data.saveToConfig().save(dataFile); data.saveToConfig().save(dataFile);
@@ -99,7 +97,7 @@ public class FileDataManager implements IDataManager {
// 只需要给没有存档的新玩家初始化一个存档数据即可 // 只需要给没有存档的新玩家初始化一个存档数据即可
PlayerData data = getPlayerData(uuid); PlayerData data = getPlayerData(uuid);
if (data == null) { if (data == null) {
playerData.add(new PlayerData(uuid)); playerData.put(uuid, new PlayerData(uuid));
} }
} }
@@ -116,33 +114,22 @@ public class FileDataManager implements IDataManager {
@Override @Override
public PlayerData getPlayerData(UUID uuid) { public PlayerData getPlayerData(UUID uuid) {
synchronized (playerData) { return playerData.get(uuid);
for (PlayerData data : playerData) {
if (uuid.equals(data.getUuid())) {
return data;
}
}
}
return null;
} }
@Override @Override
public PlayerData getPlayerData(String name) { public PlayerData getPlayerData(String name) {
synchronized (playerData) { for (PlayerData data : playerData.values()) {
for (PlayerData data : playerData) {
if (name.equalsIgnoreCase(data.getPlayerName())) { if (name.equalsIgnoreCase(data.getPlayerName())) {
return data; return data;
} }
} }
}
return null; return null;
} }
@Override @Override
public ArrayList<PlayerData> getPlayerData() { public ArrayList<PlayerData> getPlayerData() {
synchronized (playerData) { return new ArrayList<>(playerData.values());
return new ArrayList<>(playerData);
}
} }
@Override @Override

View File

@@ -17,6 +17,7 @@ import javax.sql.DataSource;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static cn.hamster3.currency.HamsterCurrency.getLogUtils; import static cn.hamster3.currency.HamsterCurrency.getLogUtils;
@@ -27,13 +28,13 @@ public class SQLDataManager implements IDataManager {
private final String database; private final String database;
private final DataSource datasource; private final DataSource datasource;
private final HashSet<PlayerData> playerData; private final Map<UUID, PlayerData> playerData;
private final HashSet<CurrencyType> currencyTypes; private final HashSet<CurrencyType> currencyTypes;
public SQLDataManager(HamsterCurrency plugin) throws SQLException, ClassNotFoundException { public SQLDataManager(HamsterCurrency plugin) throws SQLException, ClassNotFoundException {
this.plugin = plugin; this.plugin = plugin;
parser = new JsonParser(); parser = new JsonParser();
playerData = new HashSet<>(); playerData = new ConcurrentHashMap<>();
currencyTypes = new HashSet<>(); currencyTypes = new HashSet<>();
ConfigurationSection datasourceConfig = FileManager.getPluginConfig().getConfigurationSection("datasource"); ConfigurationSection datasourceConfig = FileManager.getPluginConfig().getConfigurationSection("datasource");
@@ -150,7 +151,6 @@ public class SQLDataManager implements IDataManager {
Connection connection = datasource.getConnection(); Connection connection = datasource.getConnection();
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery(String.format("SELECT * FROM %s.%s;", database, table)); ResultSet set = statement.executeQuery(String.format("SELECT * FROM %s.%s;", database, table));
synchronized (playerData) {
while (set.next()) { while (set.next()) {
try { try {
UUID uuid = UUID.fromString(set.getString(uuidCol)); UUID uuid = UUID.fromString(set.getString(uuidCol));
@@ -159,7 +159,7 @@ public class SQLDataManager implements IDataManager {
PlayerData data = getPlayerData(uuid); PlayerData data = getPlayerData(uuid);
if (data == null) { if (data == null) {
data = new PlayerData(uuid, name); data = new PlayerData(uuid, name);
playerData.add(data); playerData.put(data.getUuid(), data);
} }
data.setPlayerCurrency(currencyType, money); data.setPlayerCurrency(currencyType, money);
getLogUtils().info("已从其他插件中加载了玩家 %s 的存档数据.", data.getUuid()); getLogUtils().info("已从其他插件中加载了玩家 %s 的存档数据.", data.getUuid());
@@ -167,8 +167,7 @@ public class SQLDataManager implements IDataManager {
getLogUtils().error(e, "导入某一条数据时发生了一个错误: "); getLogUtils().error(e, "导入某一条数据时发生了一个错误: ");
} }
} }
} for (PlayerData data : playerData.values()) {
for (PlayerData data : playerData) {
statement.executeUpdate(String.format( statement.executeUpdate(String.format(
"REPLACE INTO " + database + ".hamster_currency_player_data VALUES('%s', '%s');", "REPLACE INTO " + database + ".hamster_currency_player_data VALUES('%s', '%s');",
data.getUuid().toString(), data.getUuid().toString(),
@@ -192,18 +191,16 @@ public class SQLDataManager implements IDataManager {
Connection connection = datasource.getConnection(); Connection connection = datasource.getConnection();
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery("SELECT * FROM " + database + ".hamster_currency_player_data;"); ResultSet set = statement.executeQuery("SELECT * FROM " + database + ".hamster_currency_player_data;");
synchronized (playerData) {
while (set.next()) { while (set.next()) {
String uuid = set.getString("uuid"); String uuid = set.getString("uuid");
String string = set.getString("data"); String string = set.getString("data");
try { try {
PlayerData data = new PlayerData(parser.parse(string).getAsJsonObject()); PlayerData data = new PlayerData(parser.parse(string).getAsJsonObject());
playerData.add(data); playerData.put(data.getUuid(), data);
} catch (Exception e) { } catch (Exception e) {
getLogUtils().error(e, "从数据库中读取玩家 %s 的存档( %s )时出现了一个异常: ", uuid, string); getLogUtils().error(e, "从数据库中读取玩家 %s 的存档( %s )时出现了一个异常: ", uuid, string);
} }
} }
}
set.close(); set.close();
statement.close(); statement.close();
connection.close(); connection.close();
@@ -257,10 +254,8 @@ public class SQLDataManager implements IDataManager {
data = new PlayerData(uuid); data = new PlayerData(uuid);
getLogUtils().info("初始化玩家 %s 的存档数据.", data.getUuid()); getLogUtils().info("初始化玩家 %s 的存档数据.", data.getUuid());
} }
synchronized (playerData) { playerData.remove(data.getUuid());
playerData.remove(data); playerData.put(data.getUuid(), data);
playerData.add(data);
}
set.close(); set.close();
statement.close(); statement.close();
connection.close(); connection.close();
@@ -318,33 +313,22 @@ public class SQLDataManager implements IDataManager {
@Override @Override
public PlayerData getPlayerData(UUID uuid) { public PlayerData getPlayerData(UUID uuid) {
synchronized (playerData) { return playerData.get(uuid);
for (PlayerData data : playerData) {
if (uuid.equals(data.getUuid())) {
return data;
}
}
}
return null;
} }
@Override @Override
public PlayerData getPlayerData(String name) { public PlayerData getPlayerData(String name) {
synchronized (playerData) { for (PlayerData data : playerData.values()) {
for (PlayerData data : playerData) {
if (name.equalsIgnoreCase(data.getPlayerName())) { if (name.equalsIgnoreCase(data.getPlayerName())) {
return data; return data;
} }
} }
}
return null; return null;
} }
@Override @Override
public ArrayList<PlayerData> getPlayerData() { public ArrayList<PlayerData> getPlayerData() {
synchronized (playerData) { return new ArrayList<>(playerData.values());
return new ArrayList<>(playerData);
}
} }
@Override @Override