20. september 2010 - 15:44Der er
15 kommentarer og 1 løsning
Server + Concurrency.
Jeg er i gang med et projekt, hvor jeg laver en server applikation. Ligesom da jeg troede server applikationen var færdig, testede jeg den med nogle "spam-connections", og fandt naturligvis ud af at jeg overhovedet ikke har taget højde for Concurrency. Efter at skælde mig ud for noget så dumt, så forsøgte jeg at implementere noget synchronize, men uden held. Jeg kan simpelthen ikke gennemskue hvordan det skal se ud i sidste ende.
public class Main{ private static ServerSocket server; private static Socket socket; private static ArrayList<Client> clients;
public static void main(String [ ] args){ clients = new ArrayList<Client>(); startServer(); } public static void startServer(){ try{ server = new ServerSocket(4444); }catch(Exception e){ System.out.println("Could not create socket."); System.exit(1); }
while(true){ try{ addClient(); }catch(IOException e){ System.out.println("Could not accept socket."); System.exit(1); } } } public static ArrayList<Client> getClients(){ return clients; } public static void removeClient(Client c){ clients.remove(c); } public static void addClient() throws IOException{ socket = server.accept(); Client client = new Client(socket); clients.add(client); client.start(); } }
--------------------- Client: package main;
import java.net.Socket;
public class Client extends Thread{ private Socket socket;
public Client(Socket s){ this.socket = s; } public void run(){ System.out.println("User connected.");
//Send besked til alle online clients for(Client c : Main.getClients()){ c.send("Hello."); }
System.out.println("User disconnected."); Main.removeClient(this); } public void send(String msg){ // send besked til socket. } }
Hvis flere clienter connecter på samme tid, så får jeg naturligvis:
Exception in thread "Thread-17" java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(Unknown Source) at java.util.AbstractList$Itr.next(Unknown Source) at main.Client.run(Client.java:13)
Nogle der har et forslag til hvordan jeg kan implementere en løsning? På forhånd tak.
Altså, lave en Client(Socket s, Main m); og starte Client i main: Client(socket, this);? Det gjorde jeg i den tidligere version, men af en underlig grund, så gjorde det mere skade end gavn, derfor jeg kom på at bruge static i stedet. Men vil lige undersøge igen, vender tilbage.
Jeg har forsøgt at pakke Client ind i synchronized, hver gang jeg benytter ArrayList clients, men jeg får stadig en stor del concurrency exceptions:
Exception in thread "Thread-200" java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(Unknown Source) at java.util.AbstractList$Itr.next(Unknown Source) at main.Client.run(Client.java:18)
public class Main{ private ServerSocket server; private Socket socket; private ArrayList<Client> clients;
public Main(){ clients = new ArrayList<Client>(); }
public void startServer(){ try{ server = new ServerSocket(4444); }catch(Exception e){ System.out.println("Could not create socket."); System.exit(1); }
Mange tak! Det virker efter hensigten. Smid gerne et svar. - Som et lille ekstraspørgsmål, jeg database klasse, bør jeg lave 1 instans der håndtere alle databaseforespørgslerne, eller bør jeg lave en instans per klient/tråd der kører?
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.