文档说ehcache是线程安全的。因此,据我所知,如果thread A
更新缓存,那么这些更新将始终对其他线程可见。
但是我想知道putAll
操作是否是线程安全的和原子的?说,我想简单地通过调用putAll
并传递Map
实际值来更新我的缓存。
说,我希望在更新时从缓存中获取一些值。我是否会收到旧值或等到缓存更新并收到新值?
答案 0 :(得分:2)
当操作只能完全执行或根本不执行时,操作是原子操作。根据{{3}},import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.text.ParseException;
import javax.swing.*;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.MaskFormatter;
@SuppressWarnings("serial")
public class TestFormattedField extends JPanel {
private JFormattedTextField txtPesquisar = new JFormattedTextField();
private JRadioButton rbNome = new JRadioButton("None");
private JRadioButton rbFormat = new JRadioButton("Format");
public TestFormattedField() {
txtPesquisar.setColumns(20);
ButtonGroup btnGroup = new ButtonGroup();
btnGroup.add(rbFormat);
btnGroup.add(rbNome);
rbNome.setSelected(true);
rbNome.setMnemonic(KeyEvent.VK_N);
rbFormat.setMnemonic(KeyEvent.VK_F);
add(txtPesquisar);
add(rbFormat);
add(rbNome);
setMask();
add(new JButton(new SetFormatAction()));
add(new JButton(new GetTextAction()));
}
private void setMask() {
MaskFormatter formatter = null;
try {
txtPesquisar.setValue(null);
if (rbNome.isSelected()) {
//clear mask to type normally
formatter = new MaskFormatter("****************************************");
formatter.setPlaceholderCharacter(' ');
} else {
//set mask
formatter = new MaskFormatter("###.###.###-##");
formatter.setPlaceholderCharacter(' ');
}
txtPesquisar.setFormatterFactory(new DefaultFormatterFactory(formatter));
txtPesquisar.requestFocus();
txtPesquisar.selectAll();
} catch (ParseException ex) {
ex.printStackTrace();
}
}
private class SetFormatAction extends AbstractAction {
public SetFormatAction() {
super("Set Format");
putValue(MNEMONIC_KEY, KeyEvent.VK_S);
}
@Override
public void actionPerformed(ActionEvent e) {
setMask();
}
}
private class GetTextAction extends AbstractAction {
public GetTextAction() {
super("Get Text");
putValue(MNEMONIC_KEY, KeyEvent.VK_G);
}
@Override
public void actionPerformed(ActionEvent e) {
final String text = txtPesquisar.getText();
try {
txtPesquisar.commitEdit();
} catch (ParseException e1) {
String title = "Incomplete Text Entry";
String msg = "Text -- " + text + " is not yet complete";
JOptionPane.showMessageDialog(TestFormattedField.this, msg, title, JOptionPane.ERROR_MESSAGE);
}
Object value = txtPesquisar.getValue();
System.out.println("text: " + text);
System.out.println("value: " + value);
}
}
private static void createAndShowGui() {
TestFormattedField mainPanel = new TestFormattedField();
JFrame frame = new JFrame("Test JFormattedField");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
操作不是原子操作。
如果在集合中遇到null元素或null键,则此方法将抛出NullPointerException,并且可能导致部分完成(因为可能只放置了一些元素)。
关于ehcache是否是线程安全的。 Ehcache专门设计为线程安全。以Interface Ehcache实现为例。
缓存是线程安全的。
但要注意线程安全并不意味着同步。那么差异是什么?
Threadsafe意味着可以从多个线程使用类,而不会出现任何错误或问题。
同步意味着一个或多个方法只能同时在一个线程中使用。
putAll
的含义是什么,让我们说putAll
来电。这两种方法都是线程安全的,但它们不同步。
因此,您无法确定线程A是否在get
之前调用putAll
而线程B调用get
putAll
。