Java Can';使用线程时,不能退出while循环

Java Can';使用线程时,不能退出while循环,java,multithreading,thread-sleep,Java,Multithreading,Thread Sleep,我知道设置一个while循环并保持运行直到线程停止运行是不好的做法,但我已经没有其他的想法了。然而,即使我求助于此(或类似于此),我仍然无法让我的程序正常运行 这是我的密码: public void phase1() { phase1CompoundLabels = new JLabel[numberOfElements]; okToShowAlternatives = false; remove(btnNewButton); revalidate();

我知道设置一个while循环并保持运行直到线程停止运行是不好的做法,但我已经没有其他的想法了。然而,即使我求助于此(或类似于此),我仍然无法让我的程序正常运行

这是我的密码:

public void phase1() {
    phase1CompoundLabels = new JLabel[numberOfElements];
    okToShowAlternatives = false;

    remove(btnNewButton);
    revalidate();
    repaint();

    while (totalNoOfPhase1Trials > 399) {
        Phase1Trial phase1Trial = new Phase1Trial(numberOfElements, elementColors);

        // this displays a set of images
        displayComplexStimulus(phase1Trial.getComplexStimulus());

        validate();

        // after calling this method the images get removed after two
        // seconds and the okToShowAlternatives variable gets its value
        // changed to true
        removeElementsAfterInterval(2000, phase1CompoundLabels);

        // while(okToShowAlternatives == false){
        // }

        // calling this method displays two images
        // displayAlternatives(phase1Trial.getcorrectImage(),
        // phase1Trial.getincorrectImage(),
        // phase1Trial.getcorrectElementIsOnLeft());


private void removeElementsAfterInterval(int milliseconds, JLabel[] labels) {
    Thread compoundThread = new Thread(new Runnable() {

        public void run() {
            try {
                Thread.currentThread().sleep(milliseconds);
                for (int i = 0; i < labels.length; i++) {
                    remove(labels[i]);
                    revalidate();
                    repaint();

                }
                okToShowAlternatives = true;
                System.out.println("OkToShowAlternatives: " + okToShowAlternatives);

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                Thread.currentThread().interrupt();
            }

        }

    });
    compoundThread.start();
}
public void phase1(){
phase1CompoundLabels=新的JLabel[元件数量];
okToShowAlternatives=假;
移除(b按钮);
重新验证();
重新油漆();
while(总Noofphase1试验>399){
阶段1试验阶段1试验=新阶段1试验(元件数量、元件颜色);
//这将显示一组图像
显示复杂刺激(phase1Trial.getComplexStimulus());
验证();
//调用此方法后,两次之后图像将被删除
//秒,OkthowAlternations变量获取其值
//变为真
删除元素安全期(2000年,第1阶段复合标签);
//while(oktoshowAlternations==false){
// }
//调用此方法将显示两个图像
//显示备选方案(phase1Trial.getcorrectImage(),
//phase1Trial.getincorrectImage(),
//第1阶段试验。GetCorrectionElementIsonLeft());
私有void removeElementsAfterInterval(整数毫秒,JLabel[]标签){
Thread compoundThread=新线程(new Runnable(){
公开募捐{
试一试{
Thread.currentThread().sleep(毫秒);
对于(int i=0;i
使用while循环(条件中包含OkthowAlternations的循环)和displayAlternations()方法调用被注释掉,如图所示,该程序在该点之前工作正常,因为图像集显示两秒钟,然后从jpanel中删除。但是,当我包含while循环时,程序停止显示图像集,我甚至无法关闭jframe。它完全没有响应


但是,当我包含一个print语句以查看OktHostElements变量的值是否更改为true时,它确实更改了。那么,while循环的条件是否不再满足,因此是否应该退出while循环并继续执行代码的下一部分?

不允许从不同的因为Swing是单线程设计的,所以如果您从不同于UI线程的线程与Swing中的组件树进行任何交互,您可能会遇到各种竞争条件和内存可见性问题

在指定延迟后,使用Swing计时器在Swing UI线程上执行代码:

ActionListener executeThisAfterDelay = ...;
Timer timer = new Timer(speed, executeThisAfterDelay);
timer.setInitialDelay(pause);
timer.start();

进一步参考,请参阅Oracle网站上的Java教程。

那么,你是说如果我在jpanel中更改组件,所有内容都必须在同一个线程中吗?我很困惑,因为这不意味着在使用gui时永远不能使用多线程吗?Erwin说的是不要与另一个线程中的swing组件交互。您仍然可以使用线程来做很多其他事情,只是不直接与gui交互components@lb91Adrian是对的。你可以使用多个线程,但它们不能直接与Swing交互。但是它们可以使用另一种方法,
EventQueue.invokeLater
来安排稍后在UI线程上运行的代码。如果需要的话另外,另一个线程甚至可以执行
EventQueue.invokeAndWait
来立即在UI线程上执行某些操作,但是您应该尝试避免后一种方法,以获得最佳的多线程性能。