2016-03-21 14 views
0

Ich versuche, 2 Threads einzurichten, die eine Ganzzahl in einer anderen Klasse entweder erhöhen oder verringern. Ich habe einige Probleme mit der Synchronisierung dieses Attributs.Synchronisiertes Attribut in anderer Klasse

Das ist meine Hauptklasse, wo ich meine Themen und Gegen Klasse einzurichten:

public class Main { 
public static void main(String[] arg) { 
    Counter c = new Counter(10000000); 
    Thread1 t1 = new Thread1(c); 
    Runnable2 r2 = new Runnable2(c); 
    Thread t2 = new Thread(r2); 
    t1.start(); 
    t2.start(); 
    System.out.println(t.getNumber()); 
    } 
} 

Dies ist meine Gegen Klasse:

public class Counter{ 
private int number; 
private static final Object countLock = new Object(); 

public Counter(int number){ 
    this.number= number; 
} 

public void increase(){ 
    synchronized(countLock){ 
     number++; 
    } 
} 

public void decrease(){ 
    synchronized(countLock){ 
     number--; 
    } 
} 

public int getNumber(){ 
    return number; 
} 

} 

Und das ist meine Thread1 Klasse: (Die runnable Klasse statt 'erstreckt Thread')

public class Thread1 extends Thread{ 
private Counter c; 

public Thread1(Counter c){ 
    this.c = c; 
} 

public void run(){ 
    for(int i = 0; i < c.getNumber(); i++){ 
     c.increase(); 
    } 
} 
} 
ist das gleiche, nur mit 'implementiert Runnable'

jedoch meine out put ist immer 10000000. Obwohl ich beide Methoden synchronisiert habe. Gibt es jemanden, der erklären kann, was vor sich geht?

+0

Sie müssen erklären, um das gewünschte Ergebnis haben wollte. Erwarten Sie, dass die 'for' Schleife endet? – bradimus

+1

@Bas Hinzufügen 't1.join(); t2.join(); 'nachdem Sie sie gestartet haben, damit die Threads ihre Aufgabe abschließen, bevor Sie einen Sysout ausführen. Ich glaube nicht, dass der Thread jemals aus der Schleife herauskommen wird, wenn 'c.getNumber()' sich weiter erhöht. Ich glaube du wolltest 'int number = c.getNumber(); für (int i = 0; i

+0

Es tut mir leid Jungs, ich habe realisiert, was ich getan habe. Der erste Thread wird jedes Mal um 1 erhöht und der zweite Thread wird jedes Mal um 1 verringert. Ich habe die Ganzzahl im Zähler auf 10000000 gesetzt, und beide Threads verwenden diese Zahl. Ich habe ein Ergebnis von 0 erwartet, aber ich habe gemerkt, dass das nicht passieren wird, wenn ich die Zahl auf 10000000 setze. Sorry Leute, ich bin nur dumm. – RandomStranger

Antwort

0

Wenn ich Ihren Code ausführen, wird System.out.println(t.getNumber()); ausgeführt, bevor einer der Threads hochgesponnen wird.

+0

Wie kann ich das beheben? – RandomStranger

+0

@Bas Das hängt davon ab, was Sie versuchen zu tun. Möchtest du warten bis beide Threads beendet sind? Wollen Sie die Threads für ein paar Sekunden laufen lassen und dann die Ausgabe schreiben? Sie müssen das gewünschte Ergebnis erklären. – bradimus

0

Zunächst einmal sollte dies eigentlich nie enden, da Sie den Wert, den Sie als obere Grenze in Ihrer for Schleife in der gleichen Schleife verwenden, erhöhen. Nicht sicher, ob dies das gewünschte Verhalten ist.

Zweitens wird Ihre System.out.println (wahrscheinlich) immer den Anfangswert Counter drucken, da die Threads keine Zeit hatten, ihre Arbeit zu erledigen. Zu Testzwecken können Sie etwas wie TimeUnit.SECONDS.sleep(10); hinzufügen. Für einen anspruchsvolleren Ansatz schlage ich jedoch vor, dass Sie sich java.util.concurrent.Executors und java.util.concurrent.ExecutorService ansehen (es gibt viele Beispiele dafür).

Drittens wird Ihr Leben viel einfacher sein, wenn Sie Ihre Counter s int number durch eine java.util.concurrent.atomic.AtomicInteger ersetzen.

0

Fügen Sie t1.join(); t2.join(); hinzu, nachdem Sie sie gestartet haben, damit die Threads ihre Aufgabe abschließen, bevor der Thread main Sysout ausführt.

Zu einem anderen Hinweis, ich glaube nicht, dass der Thread jemals aus der for loop als c.getNumber() weiter steigt kommen wird.

Ich glaube, Sie

int number=c.getNumber(); for(int i = 0; i < number; i++) {

statt

for(int i = 0; i < c.getNumber(); i++) {

Verwandte Themen