我有一个要运行的蒙特卡洛模拟,并不断更新系统当前状态的可视化。我有一个提供方法IsingModel
的类Iterator<IsingModel> metropolisIterator
。在迭代器上调用next()
将运行一个模拟周期,从而更新系统状态。系统取决于温度变量IsingModel.temperature
,可以在迭代之间进行更改。
例如
int t1 = 1;
int t2 = 2;
IsingModel model = new IsingModel(t1);
Iterator<IsingModel> mItr = model.metropolisIterator();
mItr.next() // simulation undergoes one iteration with t=t1
model.setTemperature(t2);
mItr.next() // simulation undergoes one iteration with t=t2
为了可视化我的模拟
public class IsingModelWindow extends JFrame
{
public class SpinPanel extends JPanel
{
public void setModel(IsingModel model)
{
// some code to create a visualisation
}
@Override
public void paintComponent(Graphics g)
{
// paint the visualisation
}
}
public class TemperatureSlider extends JSlider
{
// some stuff
}
private class IsingModelTask extends SwingWorker<Void, IsingModel>
{
private IsingModel model;
private Iterator<IsingModel> mItr;
public IsingModelTask(int temp)
{
model = new IsingModel(temp);
mItr = model.metropolisIterator();
}
@Override
protected Void doInBackground()
{
while(!isCancelled())
{
publish(model);
mItr.next();
}
return null;
}
@Override
protected void process(List<IsingModel> models)
{
IsingModel model = models.get(models.size() - 1);
spinPanel.setModel(model);
}
}
private SpinPanel spinPanel;
private TemperatureSlider temperatureSlider;
private IsingModelTask task;
public IsingModelWindow()
{
spinPanel = new SpinPanel();
temperatureSlider = new TemperatureSlider();
task = new IsingModelTask(temperatureSlider.getValue());
task.execute();
}
}
现在,我想做的就是能够在更改
IsingModelTask.model
时以新的温度更新temperatureSlider
,但是我相信这会引起一些线程问题。用ChangeListener
进行此操作的最佳方法是什么? 最佳答案
无论如何,您可能都会遇到线程问题:将模型传递给事件分发线程上的SpinPanel
。据我所知,该模型只有一个实例。这意味着在事件调度线程创建可视化文件(即执行setModel
中的代码)时,工作线程可能已经继续修改模型。
关于最棘手的问题:无论如何,您都需要ChangeListener
对更改做出反应。问题是:ChangeListener对新的滑块值有何作用?根据您的描述,这不能传递给EDT上的模型,因为更改可能会干扰当前在后台工作线程上更新的模型。务实的解决方案是将新的,更新的值从滑块直接传递到IsingModelTask
,然后通过doInBackground
方法将其传递到模型。
关于java - 与正在运行的SwingWorker进行通信,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21606851/