当我设置数字[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
>
如果您愿意,您可以创建一个包含 CommonLock
和 AtomicInteger
的单个类,使管理稍微容易一些,但我将把它留给您
关于java - 修改 EDT 中的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44320751/