Avatar billede dje1000 Nybegynder
11. februar 2005 - 17:39 Der er 6 kommentarer

Trådprogrammering hvordan tilføjer jeg synkronisering til koden

Hej jeg er i gang med at lave projekt der giver to tråde mulighed for på skift at komme til. Den måde jeg har løst det på er ikke helt optimalt, da jeg bruger en wait som er sat til 1 millisekund. Herved kan mine to tråde skiftevis få adgang til min liste med objekter, hvis den ikke var der, ville den ene tråd køre hele tiden. Som sagt er dette ikke den mest optimale løsning, da den godt kan blive langsom, hvis det nu var 10.000 gange dette forløb skulle udføres. (1 millisekund x 10.000)

Jeg har forsøgt mig lidt med synkronisering, men jeg kan ikke rigtigt få det til at virke. Mine 3 klasser er vist neden under, hvis i kan fortælle mig løsningen, ville det være fint.

/*
* Kø.java
*
* Created on 9. februar 2005, 07:50
*/
import java.util.LinkedList;
/**
*
* @author
*/
public class Kø
{
    private LinkedList hægtetListe;
   
    /** Creates a new instance of Kø */
    public Kø()
    {
        hægtetListe = new LinkedList();
    }
   
    // Indsætter et element i køens hale
    // Precondition: Der er mindre end 50 elementer i køen.
    // Postcondition: antallet af elementer er forøget med en.
    public synchronized void indsæt(Object element)
    {
        // hvis køen er fuld (har 50 elementer).
        // så skal der ikke indsættes noget element
        if(hægtetListe.size() >= 50)
        {
            System.out.println("Køen er fyldt op(" + hægtetListe.size() + "). der kan ikke indsættes flere elementer.");
        }
        else
        {
            hægtetListe.addLast(element);
            System.out.println("Nyt element tilføjet. størrelse: " + hægtetListe.size());
        }
    }
   
    // Udtager et element fra køens hoved og returnerer det.
    // Precondition: Køen har mindst 1 element.
    // Postcondition: Køen har 1 element mindre.
    public synchronized Object udtag()
    {
        // hvis køen ikke er tom,
        // så kan der tages et element ud.
        if(hægtetListe.size() > 0)
        {
            Object element = hægtetListe.removeFirst();
            System.out.println("Element fjernet. størrelse:" + hægtetListe.size());
            return element;
        }
        else
        {
            System.out.println("Køen er tom(" + hægtetListe.size() + "). der kan ikke fjernes noget element.");
            return null;
        }
    }
   
}

------Indsæt klasse --------

/*
* Indsætter.java
*
* Created on 9. februar 2005, 07:51
*/

/**
*
* @author
*/
public class Indsætter extends Thread
{
    private Kø kø;
   
    /** Creates a new instance of Indsætter */
    public Indsætter(Kø kø)
    {
        this.kø = kø;
    }
   
    // Indsætter et element i det fælles køobjekt.
    public void indsæt(Object element)
    {
        kø.indsæt(element);
        // der ventes et kort øjeblik. Dette bevirker at andre tråde har
        // mulighed for at tilgå det fælles objekt mens denne tråd sover.
        vent(1);
    }
    // lader tråden sove et kort øjeblik
    // ventetid = tid i millisekunder
    private void vent(int ventetid)
    {
        try
        {
            Thread.currentThread().sleep(ventetid);
        }
        catch (Exception e)
        {
            System.out.println("Fejl i Indsætter, metode vent" + e);
        }
    }
    public void run()
    {
        // Tester om der kan indsættes et givent antal elementer.
        for (int i=0; i < 10;i++)
        indsæt(new Object());
    }
   
}


-------- Udtag klasse -------------


/*
* Udtager.java
*
* Created on 9. februar 2005, 07:51
*/

/**
*
* @author
*/
public class Udtager extends Thread
{
    private Kø kø;
    private Object sidstUdtagneElement;
   
    /** Creates a new instance of Udtager */
    public Udtager(Kø kø)
    {
        this.kø = kø;
    }
   
    // Udtager elementet i køens hoved.
    public void udtag()
    {
        sidstUdtagneElement = kø.udtag();
        // der ventes et kort øjeblik. Dette bevirker at andre tråde har
        // mulighed for at tilgå det fælles objekt mens denne tråd sover.
        vent(1);
        // her kunne kode der tager elementet i brug implementeres.
        // Dette er dog ikke ønsket i dette projekt.
    }
   
    // lader tråden sove et kort øjeblik
    // ventetid = tid i millisekunder
    private void vent(int ventetid)
    {
        try
        {
            Thread.currentThread().sleep(ventetid);
        }
        catch (Exception e)
        {
            System.out.println("Fejl i Indsætter, metode vent" + e);
        }
    }
   
    public void run()
    {
        // Tester om der kan udtages et givent antal elementer.
        for (int i=0; i < 20;i++)
        {
            udtag();
        }
    }
   
}
Avatar billede jakoba Nybegynder
11. februar 2005 - 17:44 #1
istedet for wait(nr) kan du bruge yield();

sæt den ind de steder du nu siger wait, så vil Java VM hver gang checke efter on en anden tråd har lyst til at køre, hvis ikke kærer denn blot videre.
Avatar billede dje1000 Nybegynder
11. februar 2005 - 17:55 #2
Ja kan se det virker, men jeg var nu ude efter den smukke løsning med synkronisering, for mig at se gør yield(); det samme som min wait.
Avatar billede dje1000 Nybegynder
11. februar 2005 - 17:59 #3
Jeg ville gerne have det til at virke med notify() eller notifyAll()
Avatar billede arne_v Ekspert
11. februar 2005 - 18:54 #4
Noget ligesom den her:

import java.util.*;

public class Queue {
  private LinkedList q;
  public Queue() {
      q = new LinkedList();
  }
  public synchronized void enqueue(Job j) {
      q.addLast(j);
      notifyAll();
  }
  public synchronized Job dequeue() throws InterruptedException {
      while(q.isEmpty()) {
        wait();
      }
      return (Job)q.removeFirst();
  }
  public synchronized boolean isDone() {
      return q.isEmpty();
  }
}

?
Avatar billede arne_v Ekspert
11. februar 2005 - 18:57 #5
Hvis du allerede er på Java 1.5.x så prøv og kig på:

java.util.concurrent.ArrayBlockingQueue<E>
Avatar billede arne_v Ekspert
25. februar 2005 - 20:31 #6
dje>

Kommet videre ??
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