实例变量在线程运行(Thread Run())后为空 – Java中的扑克骰子程序

huangapple go评论72阅读模式
英文:

Instance variable is empty after Thread Run() - Poker Dice Program in Java

问题

我正在创建一个扑克骰子游戏,但我在获取实例变量的List的值时遇到了问题。

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

这个List的值在一个Thread的run()方法中被同时改变,该方法的功能是让五个骰子同时“滚动”。我使用add()方法将结果值(即骰子停止滚动时的值)添加到实例List中。然而,当我尝试在稍后的时间获取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); // **这个部分有效,List有值**
                    } 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为空(为什么?)**

}//end rollDice

好像在Run()结束后,List的值被删除了,我需要能够检索ArrayList的值,以便将其传递给其他方法。

英文:

I am creating a poker dice game and I am having trouble obtaining the value of a List that is an instance variable.

    public class ThrowDice { 
List&lt;String&gt; result = new CopyOnWriteArrayList&lt;&gt;();

The value of this List is changed concurrently in a Thread run() method whose function is to set the five dice "rolling" at the same time. I am adding the resulting value (that is, the value of the die when it stops rolling) in the instance List with add(), however when I attempt to retrieve the value of the List later on, (for example, at the end of the rollDice method itself), the array is empty.

The code:

void rollDice(JLabel k, JLabel q, JLabel j, JLabel n, JLabel t, JLabel a) throws InterruptedException {
new Thread() {
@Override
public void run() {
String res = &quot;&quot;;
try {
int times = 8;
for (int i = 0; i &lt;= times; i++) {
int random = (int) (Math.random() * 6) + 1;
switch (random) {
case 1:
k.setVisible(true);
res = &quot;k&quot;;
break;
case 2:
q.setVisible(true);
res = &quot;q&quot;;
break;
case 3:
j.setVisible(true);
res = &quot;j&quot;;
break;
case 4:
t.setVisible(true);
res = &quot;t&quot;;
break;
case 5:
n.setVisible(true);
res = &quot;n&quot;;
break;
case 6:
a.setVisible(true);
res = &quot;a&quot;;
break;
}
Thread.sleep(300);
if (i == times) {
result.add(res);
System.out.println(&quot;The result is &quot; + 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(&quot;The result is &quot; + result);// **--------------- List is empty (why?)**
}//end rolldice

}

It is as if the values of the List get deleted after Run() ends, and I need to be able to retrieve the ArrayList value so that it can be passed to other methods.

答案1

得分: 1

第二个println()调用几乎肯定会发生在rollDice()函数的第一次sleep(300)调用中仍然在睡眠时发生。(即,在任何内容被添加到列表之前。)

Johannes Kuhn建议您“尝试使用.join线程。”他的意思是:

Thread t = new Thread() {

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

t.start();
t.join();    // 这会_等待_直到线程完成其工作。
System.out.println(...);

但是,这个建议存在一个问题:也就是说,在.start()之后的紧接着的语句中_从不_有任何意义去.join()线程。线程的整个目的在于它们可以_并发地_彼此工作。

这是有意义的:

t.start();
与线程t同时进行其他操作(...);
t.join();
英文:

The second println() call almost certainly happens while the rollDice() function still is sleeping in its first call to sleep(300). (I.e., before anything has been added to the list.)

Johannes Kuhn suggested that you "Try to .join the thread." What he meant was:

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(...);

But there's a problem with that suggestion: That is, it never makes any sense to .join() a thread in the very next statement after .start()ing it. The whole point of threads is that they can work concurrently with each other.

This makes sense:

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

huangapple
  • 本文由 发表于 2020年4月6日 02:43:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/61047680.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定