Ich mag würde meine eigene Semaphore in Java implementieren (nur für die Praxis, ich bin mir dessen bewusst, dass es Semaphore-Klasse) ich es so umgesetzt haben:Meine eigene Semaphore in Java
public class MySemaphore {
private int value = 1;
public synchronized void take() {
this.value++;
this.notify();
}
public synchronized void release(){
while (this.value == 0) {
try {
wait();
} catch (InterruptedException e) {
}
}
this.value--;
}
}
I ich versuche es in einer solchen Thread zu verwenden:
public class MyThread extends Thread {
private static MySemaphore semaphore = new MySemaphore();
public void run(){
for (int i = 0; i < 100; i++) {
semaphore.take();
try {
Main.myVariable += 1;
semaphore.release();
} catch (Exception e){
System.out.println("Exception" + e.getMessage());
}
}
}
}
ich anfangen und Themen wie folgt verbinden:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static int myVariable = 0;
private static int threadsNumber = 100;
public static void main(String[] args) {
List<Thread> allThreads = new ArrayList<>();
for (int i = 0; i < threadsNumber; i++) {
allThreads.add(new Thread(new MyThread()));
}
for (int i = 0; i < threadsNumber; i++) {
allThreads.get(i).start();
}
for (int i = 0; i < threadsNumber; i++) {
try{
allThreads.get(i).join();
} catch (Exception e){
System.out.println(e.getMessage());
System.out.println("********************************");
}
}
System.out.println("Result is " + myVariable);
}
}
I will nur eine Variable 10000 mal erhöhen und ein Ergebnis erhalten. Ohne Semaphor beträgt das Ergebnis weniger als 10000 (wie 9923, 9684), was durch Nichtatomizität der Inkrementierung verursacht wird. Ich möchte diese Variable mit Semaphor schützen.
Leider ist das Ergebnis immer noch weniger als oder gleich 10000 (aber viel näher, in 9 von 10 Fällen größer als 9990). Haben Sie eine Idee, warum es passiert? Ist mein Semaphor falsch oder mache ich etwas falsch beim Starten von Threads?
Es scheint, dass Sie das 'take' bekam und' release' gemischt. 'take' (erste Operation) muss warten,' release' muss benachrichtigt werden. – JimmyB
Sie haben Recht, ich tauschte Methodennamen und das funktioniert, ich hatte nur gute Methoden, aber mit falschen Namen (und was folgt, habe ich sie falsch verwendet), danke. – Dawid
haben Sie versucht, 'AtomicInteger' zu verwenden? – diginoise