В моем проекте у меня есть класс игры, который вызывается классом клиента. На данный момент класс игры записывает путь к файлу, и класс клиента будет читать из этого файла и очищать содержимое. Я получаю слишком много конфликтов с доступом сюда, поэтому хочу использовать другой класс в качестве метода для хранения данных пути. Однако я хочу знать, будет ли еще проблема или какой будет результат, если класс игры попытается вызвать метод в классе хранения для записи, пока класс клиента в тот же момент вызывает метод в хранилище класс для чтения и очистки.На Java что происходит, если два класса называют метод в третьем классе в тот же момент?
ответ
Похоже, вам нужно подумать о потоковой передаче и синхронизации. Я бы рекомендовал прочитать «Java Concurrency на практике».
+1 - действительно хороший совет. Многопоточное программирование требует глубокого понимания того, что вы делаете. В противном случае вы в конечном итоге будете писать приложения, которые иногда не срабатывают, что трудно диагностировать. –
При наличии нескольких потоков ваши классы должны быть thread safe. Один из способов достижения этого - сделать одновременно доступные методы synchronized
.
Вот пример, чтобы вы начали:
public class Test {
public static void main(String[] args) throws Exception {
new Thread() { public void run() { Test.method(); }}.start();
new Thread() { public void run() { Test.method(); }}.start();
}
public synchronized static void method() {
System.out.println("hello ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println("world");
}
}
Без модификатора synchronized
, эта программа будет напечатали
hello
hello
world
world
Сsynchronized
ключевое слово, только один поток в то время, может звонить method
, поэтому программа печатает
hello
world
hello
world
Я предполагаю, что ваши два класса работают в отдельных потоках, поэтому они могут получить доступ к третьему классу одновременно. Доступ к ресурсу, который они читают и записывают, должен быть синхронизирован (мьютекс). Java имеет ключевое слово «synchronized», которое может использоваться несколькими способами для предотвращения параллельных модификаций и т. Д., См. here и here для получения более подробной информации.
Теоретически правильный ответ: «все может случиться».
Два вызова могут выполняться один за другим или чередовать друг с другом, результаты непредсказуемы и потенциально катастрофичны.
Именно поэтому Java предлагает вам несколько способов борьбы с этим.
Простейший (звуковой) способ заключается в том, чтобы написать ваши методы потокобезопасными. На практике это обычно означает, что вы должны использовать только локальные переменные и не должны изменять объекты, переданные вам в качестве параметров. (Никаких побочных эффектов.) Многие методы автоматически попадают в эту категорию, и в этом случае вам не нужно беспокоиться о параллелизме.
Если ваш метод не может быть потоковым, вам необходимо как-то обрабатывать одновременные вызовы.
synchronized
блоки являются наиболее часто используемыми конструкциями, но в некоторых случаях достаточно поляvolatile
или с использованием классовAtomic*
. Но этот вопрос слишком тяжел, чтобы быть охваченным одним ответом, поэтому я предлагаю вам прочитать the concurrency tutorial.
Является ли ваше приложение многопоточным или многопроцессорным? (или нет) – sinelaw
Как еще две вещи произойдут в тот же момент? – aioobe
@aioobe - вопрос @ sinelaw стоит спросить. Понятие OP о «в то же время» может отличаться от вашего и моего ...с учетом того, как формулируется вопрос. –