Avatar billede webster Nybegynder
14. august 2002 - 22:40 Der er 3 kommentarer og
1 løsning

queue

hejsan. jeg sad lige og legede med at få lavet et smart queue system et irc framework jeg arbejder på. ideen er at jeg vil have en seperat tråd til at udføre arbejdet med at sende tekst strenge til outputstreamen.

Jeg har derfor konstrueret en fifo queue der simpelt fungerer ved at threads fra mit framework kan kalde en metode der smider en tekststreng ind i queue'en. Problemet er så at queuen naturligvis er tom lang tid, og det er derfor ikke særligt smart at den tråd der skal sende står og bruger cpu tid hele tiden. Jeg har forsøgt at bruge wait() og notify() til at kunne stoppe tråden når queue'en var tom, og så lade "add" metoden starte den op igen ved nye entryes, men så får jeg forskellige exceptions der siger at jeg ikke ejer monitoren på threaden..

Mit spørgsmål er altså om nogen kan vise en opbygning hvor man kan bruge wait()/notify() til at lave en queue med læse-tråd, eller en anden smart opbyning til at opnå lignende opførsel.
Avatar billede soreno Praktikant
14. august 2002 - 22:51 #1
public class BoundedBuffer
{
  private int upperBound;
  private java.util.LinkedList buffer;

  public BoundedBuffer(int upperBound)
  {
    this.upperBound = upperBound;
    buffer = new java.util.LinkedList();
  }

  public synchronized void push(Object obj)
  {
    //denne while er løsningen på dit problem (guarded suspension)
    while(buffer.size() >= upperBound)
    {
      try
      {
        wait();
      }
      catch(InterruptedException e)
      {
          e.printStackTrace();
      }
    }

    buffer.addLast(obj);

    if(buffer.size() == 1)
      notify(); // væk én tråd, som venter på monitor
    else
      notifyAll(); // væk alle tråde, som venter på monitor
  }

  public synchronized Object pop()
  {
    while(buffer.size() == 0)
    {
      try
      {
        wait();
      }
      catch(InterruptedException e)
      {
          e.printStackTrace();
      }
    }

    Object obj = buffer.removeFirst();

    if(buffer.size() < upperBound)
      notifyAll(); // væk alle tråde, som venter på monitor

    return obj;
  }
}

så opretter du en klasse der sender objekter ind i bufferen (en producer) og en klasse der tager ud af bufferen (en consumer).
Avatar billede soreno Praktikant
14. august 2002 - 22:52 #2
hmmm, løsningen på dit problem er faktisk i pop metodens while.. :-)
Avatar billede soreno Praktikant
14. august 2002 - 23:02 #3
et eks. på producer, consumer og en main som benytter bufferen:

public class Producer extends Thread
{
  BoundedBuffer buffer;

  public Producer(BoundedBuffer buffer)
  {
    this.buffer = buffer;
  }

  public void run()
  {
    int n = 0;
    while(true)
    {
      buffer.push(new Integer(n));
      n++;
    }
  }
}

public class Consumer extends Thread
{
  BoundedBuffer buffer;

  public Consumer(BoundedBuffer buffer)
  {
    this.buffer = buffer;
  }

  public void run()
  {
    Object obj;
    while(true)
    {
      obj = buffer.pop();
      System.out.println("Hentede: " + obj);
    }
  }
}

public class Main
{
  public static void main(String args[])
  {
    BoundedBuffer buffer = new BoundedBuffer(10);//værdi valgt tilfældigt

    Producer p1 = new Producer(buffer);
    Consumer c1 = new Consumer(buffer);

    p1.start();
    c1.start();
  }
}
Avatar billede webster Nybegynder
15. august 2002 - 09:19 #4
takker =) fandt lige ud af at problemet var at jeg ikke holdte den samme monitor når jeg forsøgte at notify() som når min tråd waitede.
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester