Tenho 3 theads rolando num while em espera, como faço para liberar 1 de cada vez?

Ola pessoal!!

Preciso de uma ajuda de vocês! :wink:
Tenho um sistema de fila, cada pedido é inserido em uma Thread, em certo momento tenho 3 pedidos de uma vez… consigo segurar 2 para processar um de cada vez de acordo com o código abaixo, mais 3 não.
Como faço para liberar uma Thread por vez ??

[code]
public int send (){

aThread=new Thread(this);

aThread.start() ;


return 0;

}
public void run(){

while(main.pauseleitura10 == true){
try {
aThread.sleep(100);

        } catch (InterruptedException ex) {
            
        }

}
main.pauseleitura10 = true;

\\\\Processando pedido

\\\\fim do processamento

main.pauseleitura10 = false;

aThread.interrupt();
}

vlwwwwwwwww :smiley: !!!

Qual é realmente seu problema?

Se é ter uma fila de pedidos que devem ser atendidos, na sequência, por 3 threads diferentes (pense em um banco com 3 caixas e uma fila única - o primeiro que estiver livre atende ao cliente - decerto não é assim que se faz.

O correto é você procurar por “produtor-consumidor”, que é o nome desse tipo de situação que existe e que tem um jeito padrão de se resolver com o Java.

[quote=entanglement]Qual é realmente seu problema?

Se é ter uma fila de pedidos que devem ser atendidos, na sequência, por 3 threads diferentes (pense em um banco com 3 caixas e uma fila única - o primeiro que estiver livre atende ao cliente - decerto não é assim que se faz.

O correto é você procurar por “produtor-consumidor”, que é o nome desse tipo de situação que existe e que tem um jeito padrão de se resolver com o Java. [/quote]

Vlw pela resposta amigo, poderia me dar alguns exemplos disso?
procurei na internet mais não achei nada.

Tente o setPriority();

http://www.java-samples.com/showtutorial.php?tutorialid=302

[quote=aero_wil][quote=entanglement]Qual é realmente seu problema?

Se é ter uma fila de pedidos que devem ser atendidos, na sequência, por 3 threads diferentes (pense em um banco com 3 caixas e uma fila única - o primeiro que estiver livre atende ao cliente - decerto não é assim que se faz.

O correto é você procurar por “produtor-consumidor”, que é o nome desse tipo de situação que existe e que tem um jeito padrão de se resolver com o Java. [/quote]

Vlw pela resposta amigo, poderia me dar alguns exemplos disso?
procurei na internet mais não achei nada.[/quote]

Bom, vou dar os exemplos em inglês mesmo:

[quote=entanglement][quote=aero_wil][quote=entanglement]Qual é realmente seu problema?

Se é ter uma fila de pedidos que devem ser atendidos, na sequência, por 3 threads diferentes (pense em um banco com 3 caixas e uma fila única - o primeiro que estiver livre atende ao cliente - decerto não é assim que se faz.

O correto é você procurar por “produtor-consumidor”, que é o nome desse tipo de situação que existe e que tem um jeito padrão de se resolver com o Java. [/quote]

Vlw pela resposta amigo, poderia me dar alguns exemplos disso?
procurei na internet mais não achei nada.[/quote]

Bom, vou dar os exemplos em inglês mesmo:

Cara ta muito complicado isso… eu sou novato em threads, mais acho que não é bem isso que eu estou querendo…

Eu preciso fazer um fila de threads e executar uma por vez, me ajuda ai com exemplo pra min entende porque ta difícil :?

estou enviando uma string para cada Thread, e preciso que essa Thread entre numa fila e espere a execução das outras.

classe que envia:


ReadMessages read = new ReadMessages(stringmsg);
read.send();

classe que recebe:



public class ReadMessages implements Runnable  {

  Thread aThread=null;

  String recipient=null;


  public int step;

  public ReadMessages (String recipient){

    this.recipient=recipient;


  }

  public int send (){


    aThread=new Thread(this);

    aThread.start() ;


    return 0;
  }
  public void run(){
      
  ////Processamento ..............


 aThread.interrupt();
}
      
    
   
  }
}

O seu problema basicamente é conceitual.

É que ensinam a mexer com threads em vez de pensar em nível mais abstrato (mas que é mais concreto para as pessoas) - tarefas e executores.

O resultado líquido é que você começa a ver programas com threads que têm um monte de “sleep”, "wait " e “notify” e “setPriority” que funcionam apenas por milagre (se é que funcionam). Em particular, se um programa precisa de um “setPriority” para aparentemente funcionar, provavelmente ele está errado.

Um “executor” é algo que lida com “tarefas” e pode executá-las em paralelo com outros “executores”.

Pense num “executor” como se fosse um caixa de supermercado, e uma “tarefa” como sendo um cliente que está esperando ser atendido,

Um “executor” pode ser implementado como se fosse uma thread, ou então de outra maneira. Pode ser até implementado como um conjunto de threads, por exemplo.

No seu caso, você precisa ter o conceito de “produtor” (aquele que gera as tarefas) e “consumidor” (aquele que executa as tarefas).

Em seu lugar, eu faria algo como:

/**
 * 
 */
package guj;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Este exemplo cria um ExecutorService que é um pool de threads que irão atender aos pedidos.
 * Tempo de simulação: 1 minuto
 * Tempo em que cada thread atende a um pedido: entre 1.5 e 2.5 segundos (distribuição uniforme)
 * Quantidade de threads: 3
 * Quantidade de pedidos: 100 
 */
public class ExemploProdutorConsumidores {

    /**
     * @param args
     */
    public static void main(String[] args) throws InterruptedException {
        ExecutorService es = Executors.newFixedThreadPool(3);
        final Random r = new Random();
        for (int i = 0; i < 100; ++i) {
            final int cnt = i;
            es.execute(new Runnable() {
                @Override
                public void run() {
                    // Atendimento do pedido por uma das threads do pool de threads
                    // Note que o número da thread pode ser *8", "9" ou "10" porque qualquer programa Java,
                    // por mais simples que seja, já tem cerca de 6 a 7 threads, que são usadas
                    // pela JVM para seus propósitos.
                    System.out.printf ("Pedido %d será atendido pela thread %d %n", cnt, Thread.currentThread().getId());
                    long t = System.currentTimeMillis(); // Thread.sleep simula um processo lento
                    try { Thread.sleep (1500 + r.nextInt(1000)); } catch (InterruptedException ex) { }
                    System.out.printf ("Pedido %d atendido em %d ms %n", cnt, System.currentTimeMillis() - t);
                }
            });
        }
        es.awaitTermination(60, TimeUnit.SECONDS);
    }

}

[quote=entanglement]O seu problema basicamente é conceitual.

É que ensinam a mexer com threads em vez de pensar em nível mais abstrato (mas que é mais concreto para as pessoas) - tarefas e executores.

O resultado líquido é que você começa a ver programas com threads que têm um monte de “sleep”, "wait " e “notify” e “setPriority” que funcionam apenas por milagre (se é que funcionam). Em particular, se um programa precisa de um “setPriority” para aparentemente funcionar, provavelmente ele está errado.

Um “executor” é algo que lida com “tarefas” e pode executá-las em paralelo com outros “executores”.

Pense num “executor” como se fosse um caixa de supermercado, e uma “tarefa” como sendo um cliente que está esperando ser atendido,

Um “executor” pode ser implementado como se fosse uma thread, ou então de outra maneira. Pode ser até implementado como um conjunto de threads, por exemplo.

No seu caso, você precisa ter o conceito de “produtor” (aquele que gera as tarefas) e “consumidor” (aquele que executa as tarefas).

Em seu lugar, eu faria algo como:

[code]
/**
*
*/
package guj;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**

  • Este exemplo cria um ExecutorService que é um pool de threads que irão atender aos pedidos.

  • Tempo de simulação: 1 minuto

  • Tempo em que cada thread atende a um pedido: entre 1.5 e 2.5 segundos (distribuição uniforme)

  • Quantidade de threads: 3

  • Quantidade de pedidos: 100
    */
    public class ExemploProdutorConsumidores {

    /**

    • @param args
      */
      public static void main(String[] args) throws InterruptedException {
      ExecutorService es = Executors.newFixedThreadPool(3);
      final Random r = new Random();
      for (int i = 0; i < 100; ++i) {
      final int cnt = i;
      es.execute(new Runnable() {
      @Override
      public void run() {
      // Atendimento do pedido por uma das threads do pool de threads
      // Note que o número da thread pode ser *8", “9” ou “10” porque qualquer programa Java,
      // por mais simples que seja, já tem cerca de 6 a 7 threads, que são usadas
      // pela JVM para seus propósitos.
      System.out.printf (“Pedido %d será atendido pela thread %d %n”, cnt, Thread.currentThread().getId());
      long t = System.currentTimeMillis(); // Thread.sleep simula um processo lento
      try { Thread.sleep (1500 + r.nextInt(1000)); } catch (InterruptedException ex) { }
      System.out.printf (“Pedido %d atendido em %d ms %n”, cnt, System.currentTimeMillis() - t);
      }
      });
      }
      es.awaitTermination(60, TimeUnit.SECONDS);
      }

}
[/code][/quote]

entanglement agradeço pelo exemplo, é algo assim que preciso.
O problema é a classe fornecedora a qual dei um exemplo não pode parar para esperar o processamento. então ela cria uma thread com o pedido e assim vai …varios pedidos

A pergunta agora é, como faço para ir armazenando os pedidos nesse “executor”?

Vou fazer um exemplo mais completo. Vou criar algumas classes - “pedido” é um pedido mesmo, “vendedor” é o cara que faz os pedidos, “operário” é o cara que atende aos pedidos e fabrica o estipulado no pedido.
Vou fazer uma simulação de 3 vendedores e 4 operários.
Dá um tempinho minuto.

/**
 * 
 */
package guj;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class Pedido {
    public int codItem;
    public int quantidade;
    public double preco;
    public int idVendedor;
    public int idPedido;

    public Pedido(int codItem, int quantidade, double preco, int idVendedor, int idPedido) {
        this.codItem = codItem;
        this.quantidade = quantidade;
        this.preco = preco;
        this.idVendedor = idVendedor;
        this.idPedido = idPedido;
    }

    public String toString() {
        return String.format("item %d, qtd %d, preço %.2f, vendedor %d, pedido %d", codItem, quantidade, preco, idVendedor,
            idPedido);
    }
}

// O cara que tira os pedidos (produtor)
class Vendedor implements Runnable {
    @Override
    public void run() {
        for (int idPedido = 1; idPedido <= nPedidos; idPedido++) {
            // Fazendo um novo pedido...
            Pedido pedido = new Pedido (100+idPedido, 2000+idPedido*10, 100.0 + 10*idPedido, idVendedor, idPedido);
            System.out.printf ("Vendedor fazendo o pedido %s%n", pedido.toString());
            es.submit (new SolicitacaoPedido (pedido, 1700)); // 1700ms é o tempo estimado para o pedido ser processado
            // Esperando antes de fazer um novo pedido. 
            try {
                Thread.sleep(ms / 2 + r.nextInt(ms));
            } catch (InterruptedException ex) {
            }
        }
    }

    /**
     * Simula um vendedor.
     * 
     * @param idVendedor O id do vendedor.
     * @param nPedidos O número de pedidos que o vendedor vai tirar.
     * @param ms O tempo entre uma venda e outra (+/- 50%).
     */
    public Vendedor(int idVendedor, int nPedidos, int ms, ExecutorService es) {
        this.idVendedor = idVendedor;
        this.nPedidos = nPedidos;
        this.ms = ms;
        this.es = es;
    }

    private int nPedidos;
    private int idVendedor;
    private int ms;
    private ExecutorService es;
    private static Random r = new Random();
}

// O cara que atende aos pedidos (consumidor)
class SolicitacaoPedido implements Runnable {
    public SolicitacaoPedido (Pedido pedido, int ms) {
        this.pedido = pedido;
        this.ms = ms;
    }
    @Override
    public void run() {
        // Processa apenas um pedido (note que o "esOperarios" pega esta tarefa, ou pedido, 
        // e faz o devido processamento de um único pedido. 
        // Este é o tempo simulado de processar o pedido:
        long t = System.currentTimeMillis();
        try {
            Thread.sleep(ms / 2 + r.nextInt(ms));
        } catch (InterruptedException ex) {
        }
        System.out.printf ("Pedido atendido pela thread %s após %d ms: %s%n", 
            Thread.currentThread().getName(),
            System.currentTimeMillis() - t,
            pedido.toString());
    }
    private Pedido pedido;
    private int ms;
    private static Random r = new Random();
}

/**
 * Simulação de 3 vendedores e 4 operários. Um vendedor tira 100 pedidos a cada 2000 ms (+/- 500ms). Um operário fabrica
 * 1 pedido em 1700 ms (+/- 500ms).
 */
public class ExemploProdutorConsumidores {

    /**
     * @param args
     */
    public static void main(String[] args) throws InterruptedException {
        ExecutorService esVendedores = Executors.newFixedThreadPool(3);
        ExecutorService esOperarios = Executors.newFixedThreadPool(4);
        for (int i = 1; i <= 3; ++i) {
            esVendedores.submit(new Vendedor(i, 100, 2000, esOperarios));
        }
        esVendedores.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        esOperarios.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
    }

}

[quote=entanglement][code]
/**
*
*/
package guj;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class Pedido {
public int codItem;
public int quantidade;
public double preco;
public int idVendedor;
public int idPedido;

public Pedido(int codItem, int quantidade, double preco, int idVendedor, int idPedido) {
    this.codItem = codItem;
    this.quantidade = quantidade;
    this.preco = preco;
    this.idVendedor = idVendedor;
    this.idPedido = idPedido;
}

public String toString() {
    return String.format("item %d, qtd %d, preço %.2f, vendedor %d, pedido %d", codItem, quantidade, preco, idVendedor,
        idPedido);
}

}

// O cara que tira os pedidos (produtor)
class Vendedor implements Runnable {
@Override
public void run() {
for (int idPedido = 1; idPedido <= nPedidos; idPedido++) {
// Fazendo um novo pedido…
Pedido pedido = new Pedido (100+idPedido, 2000+idPedido10, 100.0 + 10idPedido, idVendedor, idPedido);
System.out.printf (“Vendedor fazendo o pedido %s%n”, pedido.toString());
es.submit (new SolicitacaoPedido (pedido, 1700)); // 1700ms é o tempo estimado para o pedido ser processado
// Esperando antes de fazer um novo pedido.
try {
Thread.sleep(ms / 2 + r.nextInt(ms));
} catch (InterruptedException ex) {
}
}
}

/**
 * Simula um vendedor.
 * 
 * @param idVendedor O id do vendedor.
 * @param nPedidos O número de pedidos que o vendedor vai tirar.
 * @param ms O tempo entre uma venda e outra (+/- 50%).
 */
public Vendedor(int idVendedor, int nPedidos, int ms, ExecutorService es) {
    this.idVendedor = idVendedor;
    this.nPedidos = nPedidos;
    this.ms = ms;
    this.es = es;
}

private int nPedidos;
private int idVendedor;
private int ms;
private ExecutorService es;
private static Random r = new Random();

}

// O cara que atende aos pedidos (consumidor)
class SolicitacaoPedido implements Runnable {
public SolicitacaoPedido (Pedido pedido, int ms) {
this.pedido = pedido;
this.ms = ms;
}
@Override
public void run() {
// Processa apenas um pedido (note que o “esOperarios” pega esta tarefa, ou pedido,
// e faz o devido processamento de um único pedido.
// Este é o tempo simulado de processar o pedido:
long t = System.currentTimeMillis();
try {
Thread.sleep(ms / 2 + r.nextInt(ms));
} catch (InterruptedException ex) {
}
System.out.printf (“Pedido atendido pela thread %s após %d ms: %s%n”,
Thread.currentThread().getName(),
System.currentTimeMillis() - t,
pedido.toString());
}
private Pedido pedido;
private int ms;
private static Random r = new Random();
}

/**

  • Simulação de 3 vendedores e 4 operários. Um vendedor tira 100 pedidos a cada 2000 ms (+/- 500ms). Um operário fabrica

  • 1 pedido em 1700 ms (+/- 500ms).
    */
    public class ExemploProdutorConsumidores {

    /**

    • @param args
      */
      public static void main(String[] args) throws InterruptedException {
      ExecutorService esVendedores = Executors.newFixedThreadPool(3);
      ExecutorService esOperarios = Executors.newFixedThreadPool(4);
      for (int i = 1; i <= 3; ++i) {
      esVendedores.submit(new Vendedor(i, 100, 2000, esOperarios));
      }
      esVendedores.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
      esOperarios.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
      }

}
[/code][/quote]

Maravilha de exemplo!!

Vlw pela ajuda! agora eu entendi como esse trem funciona!

VlWW!!!