java - 修改 EDT 中的变量

标签 java multithreading user-interface awt edt

当我设置数字[0] = 10时,我的循环没有停止,当按下jbutton时,while循环的线程看不到正在更改的数字,我该如何解决这个问题?我相信线程被阻塞了。

    public class A{

        private int[] number = new number[1];
        private number_game gui;


        public A(){
        }

        public void thread_loop(){

            gui = new number_game();
            gui.the_game(number);

            Thread nums = new Thread(){

                public void run(){

                    while(number[0]!= 10){

                           if(number != 10)
                              System.out.println("wrong number")
                    }

                };nums.start();

            } 
        }

    }

public class number_game extends Jframe{

......

    public number_game(){}

    / creating gui
    public void the_game(int [] guess){

       .............
       checkguess.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e){

                  guess[1] = 10;
                  dispose();

            }
        });
   }
}

public class main{
    public static void main(String[]args) {

    A nums_play = new A();
    nums_play.thread_loop();
    }

}

最佳答案

我希望这只是一些线程练习。要跨线程共享值,您需要确保访问正确同步,虽然有多种方法可以做到这一点,最简单的一种可能是使用 AtomicInteger 来处理所有问题为您提供多线程访问功能。

我还包含了一个简单的“锁定”类,这意味着 Thread 不会“自由运转”失去控制,并为 UI 提供了一种方法来提醒线程发生更改已经发生,然后它可以处理该值。

所有这些都在线程监视器和 UI 类之间共享。

我强烈建议您查看Concurrency Trail其中更详细地涵盖了此信息

import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test extends JFrame {

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

    public class CommonLock {

        private ReentrantLock lock;
        private Condition condition;

        public CommonLock() {
            lock = new ReentrantLock();
            condition = lock.newCondition();
        }

        protected void lock() {
            lock.lock();
        }

        protected void unlock() {
            lock.unlock();
        }

        public void await() throws InterruptedException {
            lock();
            try {
                condition.await();
            } finally {
                unlock();
            }
        }

        public void signal() {
            lock();
            try {
                condition.signal();
            } finally {
                unlock();
            }
        }

    }

    public Test() throws HeadlessException {
        CommonLock lock = new CommonLock();
        AtomicInteger value = new AtomicInteger(0);
        ThreadMonitor monitor = new ThreadMonitor(value, lock);
        monitor.start();

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane(value, lock));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private final AtomicInteger value;
        private final CommonLock lock;

        public TestPane(AtomicInteger value, CommonLock lock) {
            this.value = value;
            this.lock = lock;
            JButton btn = new JButton("Pick");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    value.addAndGet(2);
                    lock.signal();
                }
            });
            add(btn);
        }

    }

    public class ThreadMonitor {

        private final AtomicInteger value;
        private final CommonLock lock;

        public ThreadMonitor(AtomicInteger value, CommonLock lock) {
            this.value = value;
            this.lock = lock;
        }

        public void start() {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            lock.await();
                        } catch (InterruptedException ex) {
                        }
                        int number = value.get();
                        if (number == 10) {
                            break;
                        } else {
                            System.out.println("Bad Guess");
                        }
                    }
                    System.out.println("Good guess");
                }
            });
            thread.start();
        }
    }
}

该示例将以 2 为步长递增值(从 0 开始),让您可以看到线程正在处理该值,直到达到 10 >

如果您愿意,您可以创建一个包含 CommonLockAtomicInteger 的单个类,使管理稍微容易一些,但我将把它留给您

关于java - 修改 EDT 中的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44320751/

相关文章:

java - JDBC 错误 : Before start of result set

c - 套接字寻址机制卡住了

java - 如何使用元素的中心将 BoxLayout 中的元素居中?

java - 将泛型类添加到采用泛型类型的列表

Java 6 将 utf8 转换为 iso88591 字符集并忽略不可映射的字符

java - 从 map 存储条目是否安全?它会导致内存泄漏吗?

python - 在 WSGI/apache 应用程序中强制执行每个 IP 的并发线程限制

c# - C# 中的多线程 - 更新标签

ios - 将背景图像添加到 ui Collection View

excel - 阻止 Excel 鼠标光标在按钮上闪烁