Thread.join () не выполняет код до завершения - PullRequest
0 голосов
/ 13 апреля 2020

Я выполняю задание для универа, и я пытаюсь заставить мою программу выполнить несколько алгоритмов альпиниста холма в параллельных потоках для самостоятельного обхода.

Мало того, он, кажется, сильно замедляет мой компьютер, когда я его запускаю, и использует много памяти, что иногда приводит к сбою программы. Другое дело, что он отлично работает только с двумя потоками, если вы попытаетесь удалить th3, он будет работать отлично. Возможно, причина root в том, что мой код использует слишком много памяти. В любом случае, я был бы признателен за любую помощь, которую вы, ребята, могли бы оказать мне. Спасибо!

public class Assign3 extends JFrame{
    static Boolean gridd[][];
    static String best[];
    static int bestscore;
    private static final String sequence = "NESW";

    public Assign3() {
        //setup();
        gridd = new Boolean[3][5];
        for(int i = 0;i<gridd.length;i++) {
            for(int j = 0;j<gridd[i].length;j++) {
                gridd[i][j] = false;
            }
        }
        String s[] = generateS(14);//generates a random sequence of length 14 and splits it into an array 

        Boolean grid2[][] = run(gridd,s);
        bestscore = evaluate(grid2);//evaluates a board depending on how many vertices the sequence has visited

        printb(grid2,s);//prints the sequence, the board, and the score of the board

        Thread th = new mt(s);
        th.start();
        Thread th2 = new mt(s);
        th2.start();
        Thread th3 = new mt(s);
        th3.start();

        try {
            th.join();
            th2.join();
            th3.join();
        }
        catch(Exception e){
            System.out.println("FLOPPPP");
        }
        printb(gridd,best);
    }

    public static void main(String[] args) { new Assign3(); 
    }

    public static Boolean[][] run(Boolean grid[][], String temp[]) {
        int x=0;
        int y=0;
        grid[x][y] = true;
        for(int i=0;i<temp.length;i++) {
            if(temp[i].indexOf('W')!=-1) {
                if(y==0)
                    return grid;
                else if(grid[x][y-1] ==true){
                    return grid;
                }
                else {
                    grid[x][y-1]=true;
                    y--;
                }
            }//There is similar code for the rest of the directions, but I thought I should save space
        }
        return grid;
    }

class mt extends Thread{

    private String[] s;
    private ReentrantLock mutex = new ReentrantLock();

    public mt(String[] s) {
        this.s = s;
    }

    @Override
    public void run() {
        Boolean g[][] = null;
        String temp[] = s;
        Boolean c = false;

        System.out.println(Assign3.bestscore);

        while(c==false) {
            Random r = new Random();
            int l = r.nextInt(s.length);
            int d = r.nextInt(4);
            String n = "";

            if(d==0)
                n="N";
            else if(d==1)
                n="E";
            else if(d==2)
                n="S";
            else if(d==3)
                n="W";

            temp[l] = n;

            g = Assign3.run(Assign3.gridd,temp);


            try {
                mutex.lock();
                try {
                    if(Assign3.evaluate(g)>Assign3.bestscore) {
                        c=true;
                        Assign3.bestscore = Assign3.evaluate(g);
                        Assign3.gridd = g;
                        Assign3.best=temp;
                    }
                }finally {
                    mutex.unlock();
                }
            }catch(Exception e) {}
        }
        System.out.println(Assign3.evaluate(g) + " " + Thread.currentThread().getName());
    }
}

Это мой код, и ниже прилагается результат - поток 3 даже не запускается до завершения и не выполняется, и кода после thread.join ().

Результат

РЕДАКТИРОВАТЬ: просто игнорируйте элементы панели, которые относятся к более поздней части задания.

1 Ответ

1 голос
/ 13 апреля 2020
  1. Это не join, что вызывает ваши проблемы.

  2. Если у вас не хватает памяти, должно быть исключение ... на самом деле OutOfMemoryError, который не будет раздавлен следующим:

  3. Я подозреваю, что настоящая проблема заключается в том, что скрыто этим:

    catch(Exception e) {}
    

    Это говорит: "если что-то пойдет не так не говорите мне " . Это ужасно плохой код. По крайней мере, напечатайте трассировку стека для исключения.

  4. Я не знаю, связано ли это с проблемой или нет, но использование mutex странно. Каждый поток создает свой собственный mutex и блокирует свой собственный mutex в методе run(). Это ничего не дает ...

  5. На самом деле, 4 вполне может быть связано с вашей проблемой, так как все ваши потоки, похоже, читают обновление общего состояния в Assign3 классов stati c переменных. Поскольку вы не синхронизируете доступ к структуре данных должным образом (поскольку использование mutex неэффективно), существуют потенциальные состояния гонки и аномалии памяти, которые могут вызывать любые странные вещи. (Включая 3-й поток, разрушающий вещи.)

  6. Вам не нужно расширять Thread. Все, что вам нужно сделать, это расширить Runnable, создать его экземпляр и передать его конструктору Thread. (Это не ваша проблема ... но вы все равно должны это знать.)

Когда вы исправите 3), я ожидаю, что вы получите трассировку стека, которая даст вам некоторые подсказки, которые помочь вам найти проблему для себя.

...