elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Java
| | | |-+  ¿Como gestionar un número limitado de Threads?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: ¿Como gestionar un número limitado de Threads?  (Leído 3,639 veces)
imaginawireless

Desconectado Desconectado

Mensajes: 164


......... convivimos entre ondas ..........


Ver Perfil
¿Como gestionar un número limitado de Threads?
« en: 20 Febrero 2014, 13:03 »

Hola gente.

Estoy jugando con el protocolo SNMP utilizando SNMP4J. Por ejemplo a la hora de crear un receptor de Traps, me llama la atención que ya viene preparado para definir cuantos hilos queremos ejecutar simultaneos cuando dicho servicio una vez iniciado , mediante la clase 'TheadPool'.

http://www.snmp4j.org/doc/org/snmp4j/util/ThreadPool.html

He intentado realizar lo mismo para otros servicios que he desarrollado siguiendo el código de dicha clase y demás, pero se me está complicando.
¿A alguien se le ocurre un forma de definir de una forma sencilla cuantos hilos puede por ejemplo ejecutar un ServerSocket como máximo?

Muchas gracias.


En línea

egyware


Desconectado Desconectado

Mensajes: 526



Ver Perfil WWW
Re: ¿Como gestionar un número limitado de Threads?
« Respuesta #1 en: 20 Febrero 2014, 13:08 »

Tal vez tengas que mirar con más atención al Patrón Pool

http://programacionsolida.com.ar/2012/02/patrones-de-diseno-de-creacion-object.html

Un link que encontré a la rápida te puede guiar un poco.


En línea

adastra
Endless Learner
Ex-Staff
*
Desconectado Desconectado

Mensajes: 885


http://thehackerway.com/


Ver Perfil WWW
Re: ¿Como gestionar un número limitado de Threads?
« Respuesta #2 en: 20 Febrero 2014, 13:20 »

 En java tienes el "Executor Framework" que te permite gestionar paralelamente, varios grupos de hilos. Se basa en un modelo que utiliza colas y bloqueos, el cual probablemente es uno de los patrones más utilizados en casi todos los lenguajes de programación modernos en lo que a concurrencia se refiere.
Dale un vistazo al paquete java.util.concurrent y busca tutoriales sobre su uso.
Uno muy bueno, puede ser este:


http://www.vogella.com/tutorials/JavaConcurrency/article.html
En línea

imaginawireless

Desconectado Desconectado

Mensajes: 164


......... convivimos entre ondas ..........


Ver Perfil
Re: ¿Como gestionar un número limitado de Threads?
« Respuesta #3 en: 20 Febrero 2014, 14:05 »

Muchas gracias. Voy a estudiar lo que me decís.
Un saludo.
En línea

ThinkByYourself

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Re: ¿Como gestionar un número limitado de Threads?
« Respuesta #4 en: 21 Febrero 2014, 10:09 »

No sé si es lo que buscas, pero a ServerSocket le puedes delimitar cuántas peticiones máximas quieres que maneje en el constructor con un entero:
new ServerSocket(int puerto, int peticionesSimultaneasMaximas);
En línea

No te voy a engañar.
Todos hemos sido programados para normalizar la psicopatía de las élites económicas y políticas, y para realimentar su patrón de ciega codicia.
Pantera80

Desconectado Desconectado

Mensajes: 17



Ver Perfil
Re: ¿Como gestionar un número limitado de Threads?
« Respuesta #5 en: 22 Febrero 2014, 08:44 »

Hola. Yo hice un trabajillo que consistía en crear un pool fijo de dos hilos, aunque claro, se puede cambiar con una variable:

Código:
/**************************************************************************
     * ejecuta ocho veces la tarea NumerosAleatorios que imprime diez números
     * aleatorios menores que cincuenta, mediante un pool de tan sólo dos hilos
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       
        //define un pool fijo de dos hilos
        ExecutorService executor = Executors.newFixedThreadPool(2);

        //pasa 30 tareas NumerosAleatorios al pool de 2 hilos
        for (int i = 1; i <= 30; i++) {
            executor.submit(new NumerosAleatorios());
        }

        //ordena la destrucción de los dos hilos del pool cuando hayan
        //completado todas las tareas
        executor.shutdown();
    }
}
En línea

imaginawireless

Desconectado Desconectado

Mensajes: 164


......... convivimos entre ondas ..........


Ver Perfil
Re: ¿Como gestionar un número limitado de Threads?
« Respuesta #6 en: 23 Febrero 2014, 12:02 »

Gracias por vuestras respuestas.

La idea es optimizar el uso de recursos en un servicio que está a la escucha de conexiones, sobre todo cuando lleva mucho tiempo activo.

He leído lo que me ponían 'adastra' y 'egyware'. Con ello he encontrado nuevo mundo, jejeje, los patrones de diseño. Estoy estudiando distintos patrones para ver cual se adapta mejor a lo que busco.

En cuanto lo tenga funcionando os lo pongo.

Mil gracias...
En línea

imaginawireless

Desconectado Desconectado

Mensajes: 164


......... convivimos entre ondas ..........


Ver Perfil
Re: ¿Como gestionar un número limitado de Threads?
« Respuesta #7 en: 23 Febrero 2014, 19:17 »

Hola gente. Después de leerme e intentar comprender el patrón "Object Pool", este es el resultado.

El servicio que escucha "Listener" y ejecuta el parseo de datos en un nuevo hilo llamando a "Parser" desde el pool.
Citar
public class Listener implements Runnable {

    private boolean serviceRun;
    private DatagramSocket socket;
    private SysLogParser parser;
    private DatagramPacket data;
    private Thread runThread;
    private int bufferSize;

    private void init() {
        bufferSize = 2048;
        setServiceRun(true);
    }

    @Override
    public void run() {
        init();
        try {
            System.out.println("Servicio iniciado\n");
            data = new DatagramPacket(new byte[bufferSize], bufferSize);
            socket = new DatagramSocket(10100);
            while (isServiceRun()) {
                try {
                    socket.receive(data);
                    parser = ListenerPool.getInstance().checkOut(data.getData());
                    parser.start();
                } catch (IOException e) {
                    System.out.println("Error Listener: " + e.getMessage());
                }
            }
        } catch (Exception e) {
            System.out.println("Error Listener2: " + e.getMessage());
        }
    }

    public boolean isServiceRun() {
        return serviceRun;
    }

    private void setServiceRun(boolean serviceRun) {
        this.serviceRun = serviceRun;
    }
   
    public void start(){
        if (runThread == null){
            runThread = new Thread(this);
            runThread.start();

        }
    }
   
    public void stop(){
        if (runThread != null){
            setServiceRun(false);
        }
    }
}

La clase que gestiona el pool "ListenerPool" para la clase "Parser"
Citar
public class ListenerPool {

    private static ListenerPool instance = new ListenerPool();
    private long expirationTime;
    private HashMap<Parser, Long> locked, unlocked;

    private ListenerPool() {
        expirationTime = 5000;
        locked = new HashMap<Parser, Long>();
        unlocked = new HashMap<Parser, Long>();
    }

    public static ListenerPool getInstance() {
        createInstance();
        return instance;
    }

    private static void createInstance() {
        if (instance == null) {
            synchronized(ListenerPool.class) {
                if (instance == null) {
                    instance = new ListenerPool();
                }
            }
        }
    }
   
    protected Parser create(byte[] data) {
        return new Parser(data);
    }

    public boolean validate(Parser o) {
        return true;
    }
   
    public synchronized Parser checkOut(byte[] data) {
        long now = System.currentTimeMillis();
        Parser t;
        if (unlocked.size() > 0) {
            Iterator it = unlocked.keySet().iterator();
            while (it.hasNext()) {
                t = (Parser) it.next();
                if ((now - unlocked.get(t)) > expirationTime) {
                    unlocked.remove(t);
                    expire(t);
                    t = null;
                } else {
                    if (validate(t)) {
                        unlocked.remove(t);
                        locked.put(t, now);
                        return (t);
                    } else {
                        unlocked.remove(t);
                        expire(t);
                        t = null;
                    }
                }
            }
        }
        t = create(data);
        locked.put(t, now);
        return (t);
    }

    public synchronized void checkIn(Parser t) {
        locked.remove(t);
        unlocked.put(t, System.currentTimeMillis());
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
       throw new CloneNotSupportedException();
    }
}

El parseador de datos "Parser"
Citar
public class Parser implements Runnable {

    private byte[] data;
    private Thread runThread;

    public Parser(byte[] data) {
        this.data = data;
    }

    private void show(){
        System.out.println(runThread.getId() + "@" + runThread.getName());
    }

    @Override
    public void run() {
        this.showLog();
        SysLogParserPool.getInstance().checkIn(this);
    }
   
    public void start(){
        if (runThread == null){
            runThread = new Thread(this);
            runThread.start();
        }
    }
}

Si os fijáis en la salida que nos da el método show() de "Parser". ¿No debería de manear hilos con el mismo nombre? Se están creando nuevos hilos de la clase Parser, cuando deberían tener el mismo nombre, ¿no?


Salida
Citar
11@Thread-1
12@Thread-2
13@Thread-3
14@Thread-4
15@Thread-5
16@Thread-6
17@Thread-7
18@Thread-8
etc....
En línea

adastra
Endless Learner
Ex-Staff
*
Desconectado Desconectado

Mensajes: 885


http://thehackerway.com/


Ver Perfil WWW
Re: ¿Como gestionar un número limitado de Threads?
« Respuesta #8 en: 24 Febrero 2014, 10:01 »

 Por lo que estoy viendo, estas creando un hilo de ejecución para crear una instancia del Pool, después creas más instancias "Parser" que a su vez también son hilos...
Lo normal que la clase padre (Pool) maneje múltiples hijos de ejecución desde un único hilo, es decir, que la clase Listener no debería ser Runnable, simplemente debería instanciar la clase de Pool y en dicha clase, insertar los 1 o n hilos de la clase Parser. Luego, según el patrón de "Executor", utilizando una instancia del Pool, debes arrancar (o detener) el grupo de hilos que estén asociados a dicho Pool...


Lo suyo seria algo como:

1. Listener instancia Pool
2. Desde un método de factoría de Listener (getInstance por ejemplo) crear N hilos (instancias de la clase Parser) y añadirlos a una estructura interna de la clase Pool (una Lista de objetos Parser)
3. Desde un método de la clase Listener (startThreads, iniciarHijos o como quieras llamarlo) iniciar todos los hilos asociados a la instancia Pool creada inicialmente.
En línea

imaginawireless

Desconectado Desconectado

Mensajes: 164


......... convivimos entre ondas ..........


Ver Perfil
Re: ¿Como gestionar un número limitado de Threads?
« Respuesta #9 en: 24 Febrero 2014, 13:19 »

Ok. Voy a revisarlo. Gracias por responder.
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines