Aktivt objekt - Active object

Den aktive objekt mønster afkobler metode udførelse fra metodeaktiveringen for objekter, hver bor i deres egen tråd af kontrol. Målet er at introducere samtidighed ved hjælp af asynkron metodeopkaldelse og en planlægger til håndtering af anmodninger.

Mønsteret består af seks elementer:

  • En proxy , som giver en grænseflade til klienter med offentligt tilgængelige metoder.
  • En grænseflade, der definerer metodeforespørgslen på et aktivt objekt.
  • En liste over afventende anmodninger fra klienter.
  • En planlægger , der bestemmer hvilken anmodning der skal udføres næste gang.
  • Implementering af metoden til aktivt objekt.
  • Et tilbagekald eller en variabel, hvor klienten kan modtage resultatet.

Eksempel

Java

Et eksempel på aktivt objektmønster i Java .

For det første kan vi se en standardklasse, der giver to metoder, der sætter en double til en bestemt værdi. Denne klasse er IKKE i overensstemmelse med det aktive objektmønster.

class MyClass {

    private double val = 0.0;
    
    void doSomething() {
        val = 1.0;
    }

    void doSomethingElse() {
        val = 2.0;
    }
}

Klassen er farlig i et multithreading -scenario, fordi begge metoder kan kaldes samtidigt, så værdien af ​​val (som ikke er atomisk - den opdateres i flere trin) kan være udefineret - en klassisk racetilstand. Du kan naturligvis bruge synkronisering til at løse dette problem, hvilket i dette trivielle tilfælde er let. Men når klassen først er blevet realistisk kompleks, kan synkronisering blive meget vanskelig.

For at omskrive denne klasse som et aktivt objekt kan du gøre følgende:

class MyActiveObject {

    private double val = 0.0;
    private BlockingQueue<Runnable> dispatchQueue = new LinkedBlockingQueue<Runnable>();

    public MyActiveObject() {
        new Thread (new Runnable() {
                    
                @Override
                public void run() {
                    try {
                        while (true) {
                            dispatchQueue.take().run();
                        }
                    } catch (InterruptedException e) {   
                        // okay, just terminate the dispatcher
                    }
                }
            }
        ).start();
    }

    void doSomething() throws InterruptedException {
        dispatchQueue.put(new Runnable() {
                @Override
                public void run() { 
                    val = 1.0; 
                }
            }
        );
    }

    void doSomethingElse() throws InterruptedException {
        dispatchQueue.put(new Runnable() {
                @Override
                public void run() { 
                    val = 2.0; 
                }
            }
        );
    }
}

Java 8 (alternativ)

Et andet eksempel på aktivt objektmønster i Java i stedet implementeret i Java 8, der giver en kortere løsning.

public class MyClass {
    private double val; 
    
    // container for tasks
    // decides which request to execute next 
    // asyncMode=true means our worker thread processes its local task queue in the FIFO order 
    // only single thread may modify internal state
    private final ForkJoinPool fj = new ForkJoinPool(1, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
    
    // implementation of active object method
    public void doSomething() throws InterruptedException {
        fj.execute(() -> { val = 1.0; });
    }
 
    // implementation of active object method
    public void doSomethingElse() throws InterruptedException {
        fj.execute(() -> { val = 2.0; });
    }
}

Se også

Referencer

eksterne links