【发布时间】:2015-03-06 05:46:08
【问题描述】:
这个问题是关于 volatile 关键字的用法。我有一个显示表格的摇摆应用程序,并且有一个单独的线程将行添加到表格模型中。根据this,似乎我必须将一些字段标记为易失性,以确保 EDT 看到对表模型所做的更新。但即使没有使列表不稳定,更新似乎也有效。以下是我的代码
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
JFrame frame = new JFrame("FrameDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyTableModel dm = new MyTableModel();
frame.getContentPane().add(new JScrollPane(new JTable(dm)), BorderLayout.CENTER);
new Thread(new Runnable() {
int count = 0;
@Override
public void run() {
while (true) {
dm.addElement(count++);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
frame.pack();
frame.setVisible(true);
}
class Row {
private String name;
private String value;
public Row(String name, String value) {
super();
this.name = name;
this.value = value;
}
}
class MyTableModel extends AbstractTableModel {
private List<Row> rows = new ArrayList<Test.Row>();
@Override
public int getRowCount() {
return rows.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (columnIndex == 0) {
return rows.get(rowIndex).name;
} else if (columnIndex == 1) {
return rows.get(rowIndex).value;
} else {
throw new IllegalArgumentException();
}
}
private void addElement(int i) {
rows.add(new Row("Name" + i, "Vlaue0" + i));
fireTableRowsInserted(rows.size() - 1, rows.size() - 1);
}
@Override
public String getColumnName(int column) {
return column == 0 ? "Name" : "Value";
}
}
}
在将 rows 变量标记为 volatile 之前,我想知道如果我已经工作了,为什么我必须这样做。而且,上面链接的问题也提到了synchronized 关键字。我不明白如何使用synchronized 关键字解决线程看不到最新值的问题。对此的任何解释也表示赞赏。
【问题讨论】:
标签: java multithreading swing synchronized volatile