Avatar billede guda Nybegynder
11. maj 2003 - 09:12 Der er 13 kommentarer

semaforer og monitorer i java IGEN

Hej !!

Jeg kan ikke rigtigt se forskelen immellem semaforer og monitorer !!

eksempel 1 - semafor:

public class Semafor {
  private int counter;
 
  public Semafor() {
    this( 1 );
  }
 
  public Semafor( int n ) {
    counter = n;
  }
 
  public synchronized void down() {
    while ( counter == 0 )
      try {
        wait();
      } catch ( InterruptedException e ) {
        // ignore
      }
     
    counter--;
  }
 
  public synchronized void up() {
    if ( counter == 0 )
      notify();

    counter++;
  }
}

ekempel 2 - monitor:

public class A {
  ...
 
  public void metodeA() {
    ...
  }
 
  public synchronized void metodeB {
    ...
  }
 
  public void metodeC() {
    ...
  }
 
  public synchronized void metodeD {
    ...
  }
}

"Med det reserverede ord: synchronized angiver man, at de to metoder: metodeB og metodeD er i klassens monitor."
-----------
så mit spørgsmål er: Har jeg i eksempel 1. både en semafor og en monitor, fordi der er ordet "synchronized".
Avatar billede erikjacobsen Ekspert
11. maj 2003 - 09:16 #1
Du bruger en monitor til at realisere funktionaliteten i en semafor.
Avatar billede riversen Nybegynder
11. maj 2003 - 09:19 #2
semafor er jo ikke direkte understøttet i sproget så hvis du som i eksempelt vil lave en semafor må du jo konstruere det ud fra hvad der er muligt i java
Avatar billede arne_v Ekspert
11. maj 2003 - 09:54 #3
Alle objekter (altså alt undtagen simple data typer) i Java har en
monitor.

Den monitor kan enten bruges implicit med synchronized keyword'et eller
eksplicit med wait and notify/notifyAll metoderne.

Jeg kan absolut anbefale brug af synchronized fremfor eksplicit, hvis
det er muligt. Så er der ingen risiko for at lave ged i den.

En semafor er jo principeilt bare et objekt med synkroniseret access
til som kan bruges af flere tråde.

Der er ikke noget indbygget i java til det. Normalt kan man undgå det
designmæssigt med synkroniseret adgang til an data struktur f.eks. en kø.

Det er nemt at lave en semafor med synchronized.

Men jeg tror ikke at jeg ville lave den på samme måde som dig
(både synchronized og wait/notify) foruroliger mig.
Avatar billede erikjacobsen Ekspert
11. maj 2003 - 09:59 #4
Kan man gøre det på andre måder, Arne. En semafor er
netop karakteriseret ved at den tilhørende proces skal
vente pænt i en kø, indtil det bliver dens "tur".
Avatar billede arne_v Ekspert
11. maj 2003 - 10:04 #5
Jeg sidder faktisk lige og prøver at lave et lille kode eksemple
på for at forklare hvad jeg mener.
Avatar billede arne_v Ekspert
11. maj 2003 - 10:10 #6
Men kort fortalt er jeg bange for at brugen af synchronized(this)
og this.wait/this.notify vil lave kage i den.
Avatar billede erikjacobsen Ekspert
11. maj 2003 - 10:24 #7
Det gør nu ikke noget :)

Semaforerer er primtive i forhold til en monitor, men
begge indeholder en kø. I eksemplet ovenfor "genbruger" man
bare køen for monitoren til en semafor.
Avatar billede arne_v Ekspert
11. maj 2003 - 10:46 #8
Tja. Det virker ihvertfald upåklageligt. Mit test eksempel blev til:

public class Semaphore {
    private boolean inuse;
    private int counter;

    public Semaphore() {
        inuse = false;
        counter = 0;
    }

    public synchronized void get() {
        counter++;
        while (inuse) {
            try {
                wait();
            } catch (InterruptedException e) {
                // ignore
            }
        }
        inuse = true;
        counter--;
    }
   
    public synchronized void release() {
        inuse = false;
        notify();
    }

    public synchronized boolean available() {
        return inuse;
    }

    public synchronized int waiting() {
        return counter;
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        Semaphore sem = new Semaphore();
        MyThread[] t = new MyThread[10];
        for(int i = 0; i < t.length; i++) {
            t[i] = new MyThread(sem);       
        }
        for(int i = 0; i < t.length; i++) {
            t[i].start();     
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            // ignore
        }
        System.out.println("Waiting=" + sem.waiting());
        for(int i = 0; i < t.length; i++) {
            try {
                t[i].join();       
            } catch (InterruptedException e) {
                // ignore
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("Time=" + (end - start));
    }
   
}

class MyThread extends Thread {
    private Semaphore sem;
    public MyThread(Semaphore sem) {
        this.sem = sem;
    }
    public void run() {
        sem.get();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // ignore
        }
        sem.release();
    }
}
Avatar billede arne_v Ekspert
11. maj 2003 - 10:48 #9
Tilsyneladende har SUN lavet et godt stykke arbejde så synchronized
og wait/notify også sammen virker fornuftigt.
Avatar billede erikjacobsen Ekspert
11. maj 2003 - 10:54 #10
Det er li'som ideen i en monitor ...

Men det er "snyd" i den forstand at man ikke har lavet en
semafor. Man har lavet noget der opfører sig som en semafor,
men er sluppet for en masse bøvl da køen allerede er der.
Li'som forloren hare.
Avatar billede conrad Nybegynder
11. maj 2003 - 12:01 #11
Uden at være helt sikker:

I en monitor (lavet ved synchronized) kan der kun være en proces ad gangen

Benyttes  semaphor klasser fx som jeg tidligere gav dig, så kan der tillades at flere processer kan passere semaphoren alt afhængig af hvor mange man laver
i konstruktoren:

public Semafor( int n )
{
    counter = n;
}

new Semafor(3) vil fx gøre at 3 processor kan komme til den kode der beskyttes af semaforen.
Avatar billede arne_v Ekspert
11. maj 2003 - 14:32 #12
I 95% af multithreaded apps kan man nøjes med almindelig
synchronized.

Det er nemt at kode og risikoen for at bringe sig selv i uføre
er minimal.

Hvis man starter på wait/notify skal man derimod holde tunge
lige i munden.

Jeg har set så mange eksempler på applikationer der hænger
(p.g.a. deadlock situation) eller dør efter med IllegalMonitorStateException.
Avatar billede erikjacobsen Ekspert
11. maj 2003 - 14:54 #13
Tungen? Den har nu aldrig hjuplet mig i den situation.

Men hjernen bør man ikke koble fra. For der kan jo
tænkes situationer hvor netop wait/notify er nødvendige
for at løse problemet.
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