J'aimerais créer une sorte de Producer/Consumer
application d'enfilage. Mais je ne suis pas sûr de la meilleure façon d'implémenter une file d'attente entre les deux.
J'ai donc eu deux idées (qui peuvent toutes deux être totalement fausses). J'aimerais savoir laquelle serait la meilleure et si les deux sont nulles, quelle serait la meilleure façon d'implémenter la file d'attente. C'est principalement mon implémentation de la file d'attente dans ces exemples qui me préoccupe. J'étend une classe de file d'attente qui est une classe interne et qui est thread safe. Vous trouverez ci-dessous deux exemples comportant chacun 4 classes.
Classe principale-
public class SomeApp
{
private Consumer consumer;
private Producer producer;
public static void main (String args[])
{
consumer = new Consumer();
producer = new Producer();
}
}
Classe de consommateurs-
public class Consumer implements Runnable
{
public Consumer()
{
Thread consumer = new Thread(this);
consumer.start();
}
public void run()
{
while(true)
{
//get an object off the queue
Object object = QueueHandler.dequeue();
//do some stuff with the object
}
}
}
Classe de producteur-
public class Producer implements Runnable
{
public Producer()
{
Thread producer = new Thread(this);
producer.start();
}
public void run()
{
while(true)
{
//add to the queue some sort of unique object
QueueHandler.enqueue(new Object());
}
}
}
Classe de file d'attente-
public class QueueHandler
{
//This Queue class is a thread safe (written in house) class
public static Queue<Object> readQ = new Queue<Object>(100);
public static void enqueue(Object object)
{
//do some stuff
readQ.add(object);
}
public static Object dequeue()
{
//do some stuff
return readQ.get();
}
}
OU
Classe principale-
public class SomeApp
{
Queue<Object> readQ;
private Consumer consumer;
private Producer producer;
public static void main (String args[])
{
readQ = new Queue<Object>(100);
consumer = new Consumer(readQ);
producer = new Producer(readQ);
}
}
Classe de consommateurs-
public class Consumer implements Runnable
{
Queue<Object> queue;
public Consumer(Queue<Object> readQ)
{
queue = readQ;
Thread consumer = new Thread(this);
consumer.start();
}
public void run()
{
while(true)
{
//get an object off the queue
Object object = queue.dequeue();
//do some stuff with the object
}
}
}
Classe de producteur-
public class Producer implements Runnable
{
Queue<Object> queue;
public Producer(Queue<Object> readQ)
{
queue = readQ;
Thread producer = new Thread(this);
producer.start();
}
public void run()
{
while(true)
{
//add to the queue some sort of unique object
queue.enqueue(new Object());
}
}
}
Classe de file d'attente-
//the extended Queue class is a thread safe (written in house) class
public class QueueHandler extends Queue<Object>
{
public QueueHandler(int size)
{
super(size); //All I'm thinking about now is McDonalds.
}
public void enqueue(Object object)
{
//do some stuff
readQ.add();
}
public Object dequeue()
{
//do some stuff
return readQ.get();
}
}
Et allez-y !
1 votes
Producers enqueue et Consumer dequeue, en fait. Pas l'inverse
4 votes
Oh et ne démarrez pas de threads à partir d'un constructeur ! Ce thread pourrait observer l'objet dans un état incohérent. Reportez-vous à "Java Concurrency in Practice" pour plus de détails
0 votes
Merci Zwei, l'histoire de l'enqueue est due à mon manque de concentration. Pour ce qui est du démarrage du Thread à partir du constructeur, dois-je plutôt exécuter une méthode d'intiliation et le démarrer à cet endroit, ou dois-je le démarrer à partir de la classe de la méthode principale ?