在EDT中修改变量

时间:2017-06-02 04:23:27

标签: java multithreading user-interface awt edt

当我设置数字[0] = 10时,我的循环没有停止,当按下j按钮时,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();
    }

}

1 个答案:

答案 0 :(得分:1)

我希望这只是一些线程练习。要在线程之间共享值,您需要确保正确地同步访问,同时有多种方法可以执行此操作,最简单的方法之一可能是使用AtomicInteger来处理所有多线程。线程访问功能。

我还包括一个简单的"锁定"这意味着Thread没有" t"自由轮"失控并为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();
        }
    }
}

该示例将以0为步长递增值(来自2),允许您查看处理它的线程,直到达到10

如果你愿意的话,你可以创建一个单独的类,使CommonLockAtomicInteger更加简单,使管理更容易,但我会把它留给你