我在同步的方法中增加一个int OBECNA_LICZBA。所以只有一个线程可以增加它,因此应该增加一个。但是有时它会增加3。为什么OBECNA_LICZBA会增加更多,然后再增加1?

文件输出:

AB000024
AB000026
AB000028
AB000030
AB000032
AB000034
AB000036
AB000038
AB000040
AB000042
AB000044
AB000046
AB000048
AB000050
AB000052
AB000054
AB000056
AB000058




import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.LinkedList;

import javax.swing.JOptionPane;

public class B implements Runnable {
    private static ZasobZamkniety ZASOB;
    private static LinkedList<Pracownik> LISTA;
    private static String OBECNE_INICJALY;
    private static volatile boolean NIE_ZLAMANY = true;
    private static volatile int OBECNA_LICZBA = 0;
    private final static int MIN = 0, MAX = 999999;
    private static BufferedWriter bw = null;

    public static void fabrykaWatkow(int ileWatkow, ZasobZamkniety zasob, LinkedList<Pracownik> listaPracownikow) {
        ZASOB = zasob;
        LISTA = listaPracownikow;
        OBECNE_INICJALY = listaPracownikow.get(0).getInijcaly();
        try {
            bw = new BufferedWriter(new FileWriter("plik.txt"));
        } catch (Exception e) {
            // TODO: handle exception
        }
        for (int i = 0; i < ileWatkow; i++)
            new Thread(new B()).start();
    }

    private B() {
    }

    public static synchronized int getObecnaLiczba(){
        return OBECNA_LICZBA;
    }
    public static synchronized String pobierzObecneHaslo() {
        String kombinacja = getObecnaLiczba() + "";
        while (kombinacja.length() < 6)
            kombinacja = '0' + kombinacja;
        String haslo = OBECNE_INICJALY + kombinacja;
        przewin();
        return haslo;
    }

    public static synchronized void przewin(){
        OBECNA_LICZBA++;
        if (OBECNA_LICZBA > MAX && LISTA.size() > 1) {
            OBECNA_LICZBA = MIN;
            LISTA.remove();
            OBECNE_INICJALY = LISTA.element().getInijcaly();
        }
    }

    public synchronized static void setNieZlamany(boolean wrt){
        NIE_ZLAMANY = wrt;
    }
    public static boolean getNieZlamany(){
        return NIE_ZLAMANY;
    }

    public synchronized String odpytajZasob(String hasloDoSprawdzenia){
        return ZASOB.getTresc(hasloDoSprawdzenia);
    }
    @Override
    public void run() {
        while (getNieZlamany()) {
            String hasloDoSprawdzenia = pobierzObecneHaslo();
            try {
                bw.write(hasloDoSprawdzenia);
                bw.newLine();
            } catch (Exception e) {
                e.printStackTrace();
            }
            String odpowiedz = odpytajZasob(hasloDoSprawdzenia);
            if (!odpowiedz.equals(ZasobZamkniety.ZLE_HASLO)) {
                setNieZlamany(false);
                JOptionPane.showConfirmDialog(null, odpowiedz, "ZLAMANO HASLO", JOptionPane.PLAIN_MESSAGE);
                JOptionPane.showConfirmDialog(null, odpowiedz, "Czas lamania" + (System.currentTimeMillis() - Test.START), JOptionPane.PLAIN_MESSAGE);
            } else {
                pobierzObecneHaslo();
            }
        }

    }

}

最佳答案

您在pobierzObecneHaslo()循环中有两个对while的调用,只有其中一个通过调用来写输出

bw.write(hasloDoSprawdzenia);


因此,似乎即使您仅假设一个线程,您的值也将在两次打印之间以2递增,这似乎是当前行为。

同样,代码的当前结构方式也可以防止多个线程同时增加变量,但不能阻止多个线程在读取值和调用时间之间运行

bw.write(hasloDoSprawdzenia);


因此,如果您有多个线程,也可能会出现打印混乱的问题。

09-10 09:56
查看更多