Переменная экземпляра пуста после выполнения потока () - программа покерных костей в Java - PullRequest
0 голосов
/ 05 апреля 2020

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

    public class ThrowDice { 
          List<String> result = new CopyOnWriteArrayList<>();

Значение этого Списка изменяется одновременно в методе Thread run (), функция которого состоит в том, чтобы одновременно устанавливать пять игральных костей. Я добавляю результирующее значение (то есть значение d ie, когда оно перестает катиться) в экземпляр List с помощью add (), однако, когда я пытаюсь получить значение List позже (например, в конце самого метода rollDice) массив пуст.

Код:

void rollDice(JLabel k, JLabel q, JLabel j, JLabel n, JLabel t, JLabel a) throws InterruptedException {

    new Thread() {

        @Override
        public void run() {
            String res = "";
            try {
                int times = 8;

                for (int i = 0; i <= times; i++) {

                    int random = (int) (Math.random() * 6) + 1;

                    switch (random) {
                        case 1:
                            k.setVisible(true);

                            res = "k";
                            break;
                        case 2:
                            q.setVisible(true);

                            res = "q";
                            break;
                        case 3:
                            j.setVisible(true);

                            res = "j";
                            break;
                        case 4:
                            t.setVisible(true);

                            res = "t";
                            break;
                        case 5:
                            n.setVisible(true);

                            res = "n";
                            break;
                        case 6:
                            a.setVisible(true);

                            res = "a";
                            break;
                    }

                    Thread.sleep(300);
                    if (i == times) {
                        result.add(res);
                    System.out.println("The result is " + result);// **this works, List has values**
                    } else {
                        setToFalse(k, q, j, t, a, n);

                    }

                } // end for

            } catch (InterruptedException e) {
            }

        }  //end run           

    }.start(); //end thread
 System.out.println("The result is " + result);// **--------------- List is empty (why?)**

}//end rolldice

}

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

1 Ответ

1 голос
/ 05 апреля 2020

Второй вызов println() почти наверняка происходит, когда функция rollDice() все еще спит при первом вызове sleep(300). (То есть до того, как что-либо было добавлено в список.)

Йоханнес Кун предложил вам "Попробовать .join ветку". Он имел в виду:

Thread t = new Thread() {

    @Override
    public void run() {
        ...
    }  //end run           
};

t.start();
t.join();    // This _waits_ until the thread has finished its work.
System.out.println(...);

Но есть проблема с этим предложением: то есть, никогда не имеет никакого смысла для .join() потока в следующем утверждении после .start()ing это. Весь смысл потоков в том, что они могут работать одновременно друг с другом.

Это имеет смысл:

t.start();
DoSomethingElseConcurrentlyWithThread_t(...);
t.join();
...