2017-04-13 2 views
-1

der Schwerpunkt liegt auf Java parallelen Threads. Dieser Beitrag ist nicht wirklich eine Frage, sondern ein Aufruf zu Meinungen und Vorschlägen. Aus irgendeinem Grund finde ich es schwer, den Weg zu finden, mit dem zwei parallele Threads gleichzeitig im selben Datenpool arbeiten. Ich verstehe, dass Java als eine solide und robuste Sprache geboren wird und die Gefahren der Verwendung von Zeigern vermeidet, wie es C/C++ tut.

Aber ohne Zeiger, machen einige Aufgaben wie parallele Threads arbeiten zusammen auf den gleichen Daten, erfordert einige seltsame Gedanken Wendungen ich nicht vollständig erfassen. In C/C++ müssen Sie nur Zeiger übergeben, und voila, der Auftrag ist erledigt.

Eine andere Einschränkung war, alles ohne die Verwendung von statischen Variablen und Methoden zu tun, weil ich finde, so eine einfache Flucht.Java, arbeitet parallel auf den gleichen Daten

Fangen wir ... Ich habe eine Klasse Useless:

class Useless { 
    private int a = 9; 

    synchronized public void inc() { 
    a++; 
    try { 
     Thread.sleep(100); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.println(a); 
    } 
} 

Was mit Useless zu tun? Ich instanziiere es in einer anderen nutzlosen Klasse.

class Inner extends Thread { 
    private Useless useless1 = new Useless(); 

    @Override 
    public void run() { 
    useless1.inc(); 
    } 
} 

nun die intuitive (aber falsch) Weg 2 parallele Threads zu erstellen, die auf dem gleichen useless1 Objekt arbeiten, ist wie folgt:

public class Toexe2 { 
    public static void main(String[] args) { 

    Inner in1 = new Inner(); 
    Inner in2 = new Inner(); 

    in1.start(); 
    in2.start(); 
    } 
} 

Das Problem ist klar: Ich habe 2 Instanzen von Inner und so 2 nutzlose1 Objekte, jedes innerhalb seiner inneren Klasse. Das funktioniert nicht, also ...

Der einfachste Weg, um mein Ziel zu erreichen, ist eine äußere Klasse um Inner zu machen. Inner wird das runnable sein. Aber das nutzlose Objekt, unbrauchbar1, wird nur 1 Instanz haben, wie ich will. Die komplette Datei ist dies:

package pk1; 

    import pk1.Outer; 
    import pk1.Useless; 

    class Useless { 
     private int a = 9; 

     synchronized public void inc() { 
     a++; 
     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println(a); 
     } 
    } 

    class Outer { 
     private Useless useless1 = new Useless(); 

     public class Inner extends Thread { 
     @Override 
     public void run() { 
      useless1.inc(); 
     } 
     } 
    } 

    public class Toexe { 
     public static void main(String[] args) { 

     Outer st1 = new Outer(); 
     Outer.Inner in1 = st1.new Inner(); 
     Outer.Inner in2 = st1.new Inner(); 

     in1.start(); 
     in2.start(); 
     } 
    } 

Meine Gedanken sind: Gibt es eine noch einfachste Art und Weise zu erreichen, was ich tun möchte, ohne innere Klassen zu verwenden? Das "alles ist eine Klasse" -Paradigma von Java, macht einfache Dinge sehr verdreht und kontraintuitiv. Liege ich falsch ?

+1

Wenn Sie nur eine "nutzlose" Instanz möchten, machen Sie es zu einem Singleton und fertig damit. –

+0

[So verwenden Sie ein Singleton] (https://www.tutorialspoint.com/java/java_using_singleton.htm). –

Antwort

0

Tatsächlich liegen Sie falsch. Java erlaubt im C/C++ Stil zu programmieren.

Erstens, nicht "alles ist eine Klasse". Eine Klasse mit nur statischen Elementen ist keine Klasse, sondern eine Quelldatei in C. Sie ist nur eine Kompilierungseinheit wie in Turbo Pascal.

Zweitens, Verweis in Java ist der Zeiger in C/C++. Es fehlen einige Operationen wie Inkrementieren/Dekrementieren oder Konvertieren in und aus Integer, aber wenn es als Parameter übergeben wird, ist es genau ein Zeiger. Wenn Sie also wissen, wie Sie Zeiger in C/C++ übergeben, machen Sie dasselbe in Java.

Nun, wie ich den Code ändern würde:

class Inner extends Thread { 
    private Useless useless1; 

    Inner(Useless useless1) { 
     this.useless1 = useless1; 
    } 

    @Override 
    public void run() { 
     useless1.inc(); 
    } 
} 

public class Toexe2 { 
    public static void main(String[] args) { 
     Useless useless1 = new Useless(); 

     Inner in1 = new Inner(useless1); 
     Inner in2 = new Inner(useless1); 

     in1.start(); 
     in2.start(); 
    } 
} 

Hinweis Inner hat nicht eine innere Klasse zu sein, es kann auch ein äußeres sein.

+0

Danke für die Antwort ... –

+0

@ Mario Rossi können Sie danken, indem Sie die Antwort upvotieren und akzeptieren :) –

Verwandte Themen