У меня есть простая игра XO, в которой несколько клиентов играют в XO Chess друг с другом. Я построил сервер, который связывается с каждым подключенным клиентом. (Когда клиент подключается к серверу, я создаю новый класс (реализую Runnable), обрабатываю этот сокет, затем запускаю Thread ... У меня есть список, хранящий весь клиент во внешнем классе). Когда клиент хочет начать игру, он сделайте себе новый сервер и отправьте информацию о номере (его имя, IP-адрес, порт ...) на Сервер. И на сервере у меня есть Список, который добавляет эту комнату в список и отправляет ее другим Клиентам.Java Socket - Обновление переменной экземпляра Список из темы
public class ServerController {
private ServerView view;
private ServerSocket myServer;
private int serverPort = 8881;
private List<ExchangeData> list;
private volatile List<Room> rooms;
public ServerController(ServerView view) {
this.view = view;
openServer(serverPort);
view.showMessage("TCP server is running...");
list = new ArrayList<ExchangeData>();
rooms = new ArrayList<Room>();
while (true) {
listening();
}
}
private void openServer(int portNumber) {
....
}
private void listening() {
try {
Socket clientSocket = myServer.accept();
ExchangeData ex = new ExchangeData(clientSocket);
Thread thread = new Thread(ex);
thread.start();
list.add(ex);
} catch (IOException e) {
System.out.print(e.toString());
}
}
class ExchangeData implements Runnable {
private Socket clientSocket;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private boolean run = true;
public ExchangeData(Socket socket) {
try {
clientSocket = socket;
oos = new ObjectOutputStream(clientSocket.getOutputStream());
ois = new ObjectInputStream(clientSocket.getInputStream());
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
public void closeConnection() {
.....
}
public void sendData(Object o) {
try {
oos.writeObject(o);
} catch (Exception ex) {
view.showMessage(ex.toString());
}
}
public void run() {
try {
while (run) {
Object data = ois.readObject();
if (data instanceof Object[]) {
Object[] o = (Object[]) data;
String s = o[0].toString();
if (s.equalsIgnoreCase("Open Room")) {
Room r = (Room) o[1];
String username = r.getUsername();
InetSocketAddress isa = r.getIsa();
**rooms.add(r);**
List<Room> l = new ArrayList<Room>(rooms);
for (ExchangeData ex : list) {
ex.sendData(username + " Open A room at : "
+ isa);
**ex.sendData(rooms);**
}
} else if (s.equalsIgnoreCase("Close Room")) {
Room room = (Room) o[1];
rooms.remove(room);
List<Room> l = new ArrayList<Room>(rooms);
for (ExchangeData ex : list) {
ex.sendData(l);
}
}
} else if (data instanceof String) {
String s = data.toString();
if (s.equalsIgnoreCase("Quit")) {
stopThread();
list.remove(this);
closeConnection();
}
}
}
} catch (Exception ex) {
try {
stopThread();
list.remove(this);
} catch (ExceptionInInitializerError e) {
e.printStackTrace();
}
}
}
}
}
Проблема заключается в том, когда я исполняю rooms.add (г), другие темы, кажется, не видеть, что "обновление". Например: 1) Первый игрок открывает комнату - размер номера 1; 2) Второй игрок открывает новый номер - размер комнаты теперь 2 (я попытался добавить некоторые строки кода в сторону метода sendData (Object o), который печатает размер комнаты и все равно 2. Но когда строка ObjectoutputStream .write (o), он фактически записывает значение комнат, в которых выполняется Thread (первый игрок), до которого будет 1. Если я создаю новый список, например List l = new ArrayList (комнаты), как я сделал с «Закрывающейся комнатой «Тогда отправьте это, это работает. Я не понимаю, почему? Кто-то, пожалуйста, объясните это мне. Извините за мой плохой английский :(
Вау, Большое спасибо, Низет, я потратил несколько дней, чтобы прочитать о потоковом безопасном, параллелизме и т. Д., Я мог бы проголосовать за вас. – user2747502