я впервые спрашиваю здесь. Я уже много раз помогал при поиске и всегда находил этот сайт. Но сейчас я не могу найти ответ на мою проблему. У него какая-то ситуация со многими другими вопросами, но я не могу найти тот, который мне нужен.
Хорошо, у меня есть класс с именем player, farm и land. Ферма является своего рода контроллером. У фермы есть массив объектов, называемых картой, который используется совместно с землей и игроком (предоставляется при их создании), а внутри карты находится игрок и земля.
То, что я хочу сделать, это
Я щелкнул левой кнопкой мыши на ферме и получил объект с карты в зависимости от того, где щелкнул, затем сохраняю этот объект как выбранный. Затем я щелкаю правой кнопкой мыши по другому объекту и получаю объект, давайте назовем его действующим. У Actioned есть метод getMenu (selected), который возвращает JPopMenu, основываясь на выбранном. Например, если игрок выбран и земля активирована, getMenu () вернет меню «плуг», «вода» и «движение». Если я нажму на «Плуг», то земля изменится, и, конечно же, карта также поменяется, что поделится с другим объектом.
Проблема в том, что мне нужно, чтобы игрок сначала добрался до сетки около земли, прежде чем начнется настоящее действие плуга. Таким образом, в меню плуга я добавляю ActionListener следующим образом:
new ActionListener() {
public void actionPerformed(ActionEvent e) {
int gx = (int)Point2D.this.X();
int gy = (int)Point2D.this.Y();
Object lock = new Object();
player.move(gx,gy,lock);
try {
lock.wait();
} catch (InterruptedException ex){}
// do the real action of plow here
}
}
}
И способ перемещения игрока
public void move(int gx,int gy,Object lock){
setDestination(gx, gy);
this.lock = lock;
}
Ферма является объектом Runnable, поэтому каждый раз, когда ферма будет вызывать player.Update ().
public void update(){
updatePosition();
if (position==destination) {
lock.notify();
}
}
Я подумал о том, чтобы создать там объект, называемый замком, и этот объект был передан игроку. Слушатель сам по себе является работающим потоком и запускается при нажатии на меню, поэтому я заставляю поток Слушателя ждать, основываясь на объекте блокировки. Уведомление выдается из ветки фермы.
Но, конечно, это не работает должным образом, и выкидывает исключение java.lang.IllegalMonitorStateException. Я действительно не понимаю, что такое объяснение синхронизации из Интернета. Вопрос 1: Как мне использовать синхронизацию, чтобы код работал? Или что мне делать, если синхронизация здесь никогда не сработает?
Я также подумал об использовании другого подхода.
Я делаю плеер как работающий поток. Теперь у меня есть 3 потока, ферма, слушатель (земля) и игрок.
Поэтому вместо создания объекта блокировки я создаю новый поток (Player). Метод запуска игрока:
while (position != destination) {
try {
Thread.sleep(100);
} catch (InterruptedException e){}
}
Новый метод слушателя:
Player player = (Player) selected;
int gx = (int)Point2D.this.X();
int gy = (int)Point2D.this.Y();
player.move(gx,gy);
Thread waitplayernotmoving = new Thread(player);
waitplayernotmoving.start();
try {
waitplayernotmoving.join();
} catch (InterruptedException e){}
Это достаточно хорошо работает. Вопрос 2: перестает ли работать наземный поток во время ожидания потока игрока? если нет, как заставить поток земли остановиться, ожидая, когда поток игрока мертв?
И у меня другая проблема. Если я пашу land1, а затем, пока игрок движется, я нажимаю на land2 и пашу land2, игрок поворачивается к land2! А потом, после того как он снова не движется, обе земли распахиваются! То есть поток земли1 все еще активен.
У меня два вопроса:
Вопрос 3: Можно ли заставить поток земли1 умереть, если я назначу другому игроку какое-либо действие, такое как плуг land2?
Вопрос 4: Можно ли заставить поток land2 выполняться после потока land1 на основе того, что сейчас делает моя программа? Так что действие похоже на очередь. Я пашу землю1, затем пашу землю2, действие произойдет, когда игрок переместится на землю 1, затем пашу землю 1, затем перейду на землю2 и пашу землю 2.
Вопрос 5 Помните мою карту, массив объектов, который является общим для всех? Как обеспечить его безопасность? Я имею в виду, похоже, что будет много потоков, читающих и пишущих карту. Я где-то читал, если он неизменен, это не будет проблемой. Но это переписывается так часто ... не будет ли это проблемой?
Большое спасибо за чтение этого длинного объяснения, и я надеюсь, что вы можете дать мне ответ. : (