Сообщений: 300
Тем: 92
Зарегистрирован: Oct 2010
Репутация:
-132
Доброго времени суток!!!
Помогите плз разобраться как сделать "ленивую загрузку" определенных данных из бд, в момент когда сервер уже полностью загрузился и ничто не мешает заходить простым игрокам на сервер.
сейчас у меня есть такой метод для загрузки:
Код: public static void init()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement stm = con.prepareStatement("SELECT * FROM special_bosses");
ResultSet rs = stm.executeQuery();
while(rs.next())
{
// загрузка, спавн и тд
// время загрузки 1 босса ~ 0.5сек
}
}
}
но я его запускаю в GameServer вместе с остальной загрузкой данных и не знаю как определить состояние что сервер уже "полностью" загрузился...
хотелось бы в итоге сделать так, чтобы метод вызывался не просто после полной загрузки сервера, но и данные подгружались постепенно с определенной задержкой.
например в таблице special_bosses есть 100 строк, и каждая последующая строка будет подгружаться каждые 10 секунд
использую Scoria подобную сборку
заранее биг спс!!!
Сообщений: 105
Тем: 22
Зарегистрирован: Mar 2010
Репутация:
279
Thread.Sleep(10000); ??// в миллисекундах
Ну и загрузка в отдельном потоке, так же вроде как его надо isbackground=true
Код: //где-то...
Thread th = new Thread(init);//вместо вызова самой функции init()
th.Start();
th.Join();
//---------------------
public static void init()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement stm = con.prepareStatement("SELECT * FROM special_bosses");
ResultSet rs = stm.executeQuery();
while(rs.next())
{
// загрузка, спавн и тд
// время загрузки 1 босса ~ 0.5сек
Thread.Sleep(10000);//10 сек
}
}
}
Сообщений: 252
Тем: 2
Зарегистрирован: Mar 2012
Репутация:
902
1. Зачем?
2. Если ответ на п.1 все же нашелся, то стоит посмотреть хотя бы в сторону ScheduledThreadPoolExecutor или на обертку ThreadPoolManager (или аналог), которая есть в большинстве сборок.
Сообщений: 300
Тем: 92
Зарегистрирован: Oct 2010
Репутация:
-132
kpNemo Написал:Thread.Sleep(10000); ??// в миллисекундах
Ну и загрузка в отдельном потоке, так же вроде как его надо isbackground=true
//где-то...
Thread th = new Thread(init);//вместо вызова самой функции init()
th.Start();
th.Join(); В отдельном потоке - это где?
Как такое организовать в сборке??
Что за isbackground?
Подробнее пожалуйста...
Сообщений: 3,494
Тем: 52
Зарегистрирован: Jun 2010
Репутация:
12,167
Реинтернал лок, анлок уже вижу отменили в яве ?
Я даже промолчу про атомары.
Сообщений: 2,303
Тем: 24
Зарегистрирован: Sep 2010
Репутация:
5,617
-
Ленивая загрузка не подразумевает загрузку через какой-то определенный промежуток времени.
Она подразумевает загрузку контента "по запросу", т.е. грузить только тогда, когда этот ресурс понадобился.
Реализуется обычно через IoC или синглетон.
Сообщений: 300
Тем: 92
Зарегистрирован: Oct 2010
Репутация:
-132
ANZO Написал:
-
Ленивая загрузка не подразумевает загрузку через какой-то определенный промежуток времени.
Она подразумевает загрузку контента "по запросу", т.е. грузить только тогда, когда этот ресурс понадобился.
Реализуется обычно через IoC или синглетон.
если вы не внимательно прочитали первый пост, то я вам напишу еще раз:
цель сводится к тому, чтобы по наступлению события А(полная загрузка сервера), запускать событие Б(начало загрузки доп. ресурсов)
что собственно и подразумевает под собой ленивая загрузка.
причем эти ресурсы не должны загрузиться сразу все, а каждый с определенной задержкой и по идее в отдельном потоке (чтобы не замораживать поток GameServer)
здесь кто нибудь может подсказать реально по делу и написать пару простых и разьясняющих строк кода?
Сообщений: 252
Тем: 2
Зарегистрирован: Mar 2012
Репутация:
902
Я вам написал предельно по делу, за что еще и минус получил. Чтобы не грузить один поток, достаточно запустить задачу в другом, зачем делать таймаут в N секунд я не понимаю, но если очень хочется - ScheduledThreadPoolExecutor, что я и писал выше.
Пару строк кода? Вот:
Код: ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(4);
pool.scheduleAtFixedRate(() -> System.out.println("do task"), 0, 1000, TimeUnit.MILLISECONDS);
И выше вам верно написали, ленивой загрузкой в данном случае будет загрузка и spawn РБ в момент, когда игрок зайдет в этот квадрат. То, что вы просите, ленивой загрузкой называть некорректно.
Сообщений: 2,303
Тем: 24
Зарегистрирован: Sep 2010
Репутация:
5,617
mego4el Написал:если вы не внимательно прочитали первый пост, то я вам напишу еще раз:
цель сводится к тому, чтобы по наступлению события А(полная загрузка сервера), запускать событие Б(начало загрузки доп. ресурсов)
что собственно и подразумевает под собой ленивая загрузка.
причем эти ресурсы не должны загрузиться сразу все, а каждый с определенной задержкой и по идее в отдельном потоке (чтобы не замораживать поток GameServer)
здесь кто нибудь может подсказать реально по делу и написать пару простых и разьясняющих строк кода?
Это вы, видимо, не очень вникаете в суть того, что вам пишут. Я вам ЕЩЕ раз повторяю, что ленивая загрузка к тому что вы описываете вообще никаким образом не относится и ваше описание и подоход является бредом сивой кобылы (как заметил товарищ ProDev: ленивая загрузка ресурса - это когда ресурс грузится только при обращении к нему, а не во время инициализации приложения).
В данном конкретном случае, если вам нужная некая событийность: реализуйте тип листенера (хука, хэндлера или чего у вас там), который будет дергать подписанные на это событие экземпляры классов при ON_SERVER_STARTED. Вариантов в самом деле масса - все зависит от кривости сборки и рук реализующего.
Сообщений: 2,455
Тем: 53
Зарегистрирован: Apr 2010
Репутация:
19,728
Так.
Код: @Startup("Skills")
@Singleton
@Slf4j
public class SkillExtender implements Reloadable {
@Getter(lazy=true) private final static SkillExtender instance = new SkillExtender();
private SkillExtender() {
ThreadPoolManager.getInstance().executeGeneral(this::reload);
}
@Override
public void reload() {
...
}
}
Или так.
Код: @Startup("Items")
@StartupSingleton
@Slf4j
class CrownTable implements Reloadable {
private static CrownTable instance;
static def CrownTable getInstance() {
instance ?: (instance = new CrownTable());
}
private CrownTable() {
ThreadPoolManager.getInstance().executeGeneral([run: reload()] as Runnable);
}
@Override
def void reload() {
...
}
}
Или даже так:
Код: @Slf4j
public class SpawnEventRotator extends GameTimeStateEvent implements Reloadable {
@Getter(lazy=true) private final static SpawnEventRotator instance = new SpawnEventRotator();
private final String night = "NIGHT";
private final String day = "DAY";
private SpawnEventRotator() {
reload();
}
@Override
public void reload() {
Future<?> future1 = ThreadPoolManager.getInstance().executeGeneral(() -> despawn(XSpawnCache.getInstance().getSpawn(day)));
Future<?> future2 = ThreadPoolManager.getInstance().executeGeneral(() -> despawn(XSpawnCache.getInstance().getSpawn(night)));
try {
future1.get();
future2.get();
} catch(ExecutionException e) {
log.error("Failed to reload event rotator", e);
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
...
}
}
А еще есть крутая вещь CountDownLatch.
m0nster.art - clear client patches, linkz to utils & code.
Гадаю по капче.
|