请考虑以下课程:
public class Money {
private double amount;
public Money(double amount) {
super();
this.amount = amount;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public Money multiplyBy( int factor) {
this.amount *= factor;
return this;
}
}
我可以采取哪些预防措施来确保此类在多线程方面没有任何问题。有很好的表现。同时确保货币精度不会成为问题
答案 0 :(得分:0)
有两个关键点可以使POJO(普通旧Java对象)线程安全:
使类不可变。如果添加任何实例变量,请将其设置为final或volatile。
使您的吸气剂和设置器同步,即
public synchronized void setAmount(double amount) {}
答案 1 :(得分:0)
理想情况下,如果您将一个类设为不可变的,则不必担心多线程。但是在这里,您应该使multipleBy方法可以相互执行,以便它不会出现不一致的行为。 另外,您无需提供设置器,因为唯一的构造函数将数量作为参数。
答案 2 :(得分:0)
艾哈迈德,你的问题是模棱两可的笑声。
关于多线程:目前尚不清楚多线程问题意味着什么。例如,该类在同步方面没有任何问题,但是您仍然可以通过多个线程利用它来将Money对象的状态设置为混乱:
public class Money {
private volatile double amount;
public Money(double amount) {
super();
this.amount = amount;
}
public double getAmount() {
return amount;
}
public synchronized void setAmount(double amount) {
this.amount = amount;
}
public synchronized Money multiplyBy( int factor) {
this.amount *= factor;
return this;
}
}
关于货币精度:正如Andreas回答的那样,请参阅:Why not use Double or Float to represent currency?。同样可能很有趣:What is the best data type to use for money in Java app?
答案 3 :(得分:0)
有几种保持精度的方法。第一种是完全避免使用float
和double
s这样的定精度浮点二进制数类型(如果您的货币使用的是十进制数字)。这里有一些不错的选择:
BigDecimal
java.math.BigDecimal
允许您轻松存储精确的有限长度的十进制值,但这可能会有点慢。
如果您需要简化编程和精确计算结果,请使用BigDecimal
,但是您可以放慢速度。
long
long
可用于以美分而不是美元来存储金额。如果您使用的是美国货币。
对于其他货币,您可以获取货币面额的有理GCD的倒数,然后在存储时将所有乘以该值。
如果您需要非常快的速度并且可以接受long
,则缺点是货币金额大于92,233,720,368,547,758.07美元会得出完全错误的结果。
long
除了自身速度很快之外,还使用了更少的内存,并且从不需要垃圾收集,因此这对他们来说又是一个很小的提速。
BigInteger
long
可以替换为java.math.BigInteger
s,以避免出现任何溢出问题。
如果您希望在其他两个的速度和速度之间保持某种速度,而又没有合理的机会发生溢出,请使用此功能。