我正在努力理解ExecutorService,以及它将如何避免使用同步关键字。我尝试了这样的方法(为了清晰起见,避免进口),结果是错误的:
public class ReadWebPage
{
public static void main(String[] args)
{
ExecutorService executor = Executors.newFixedThreadPool(5);
FinTrans ft = new FinTrans ();
TransThread tt1 = new TransThread (ft, "Deposit Thread");
TransThread tt2 = new TransThread (ft, "Withdrawal Thread");
executor.submit(tt2);
executor.submit(tt1);
executor.shutdown();
}
}
class FinTrans
{
public static String transName;
public static double amount;
}
class TransThread implements Runnable
{
private FinTrans ft;
private String name;
TransThread (FinTrans ft, String name)
{
this.name = name;
this.ft = ft;
}
public String getName(){
return name;
}
public void run ()
{
for (int i = 0 ; i < 10 ; i++ )
{
if (getName ().equals ("Deposit Thread"))
{
ft.transName = "Deposit";
try
{
Thread.sleep ((int) (Math.random () * 100));
}
catch (InterruptedException e)
{
}
ft.amount = 2000.0;
System.out.println (ft.transName + " " + ft.amount);
}
else
{
ft.transName = "Withdrawal";
try
{
Thread.sleep ((int) (Math.random () * 10));
}
catch (InterruptedException e)
{
}
ft.amount = 250.0;
System.out.println (ft.transName + " " + ft.amount);
}
}
}
}这给了我错误的结果:
Deposit 250.0 //wrong
Withdrawal 250.0
Withdrawal 250.0
Withdrawal 250.0
Withdrawal 250.0
Withdrawal 250.0
Withdrawal 250.0
Withdrawal 250.0
Withdrawal 250.0
Withdrawal 2000.0 //wrong
Deposit 250.0 //wrong
Deposit 2000.0
Deposit 2000.0
Deposit 2000.0
Deposit 2000.0
Deposit 2000.0
Deposit 2000.0
Deposit 2000.0
Deposit 2000.0
Deposit 2000.0请您解释一下这里出了什么问题? 1.这是因为两个运行库共享同一个FinTrans对象吗? 2.这是否意味着我们在这里也需要相同的旧同步机制?
我试图了解在什么情况下我们可以使用ServiceExecutors
阿南德
发布于 2014-12-17 06:08:46
ExecutorService并行运行作业,但不会自动安全地跨线程并发访问共享状态。所以,对你问题的两个部分都说“是的”。
FinTrans状态对象的两个运行程序造成的。执行器很适合异步提交任务,并且能够通过返回的Future实例检查它们的状态(例如,它们是否已经完成)。
发布于 2014-12-17 06:18:06
在异步处理的情况下,需要有同步块。如果您试图模拟银行帐户,使用java进行处理,例如,您可以使用一些java并发原语。
使用AtomicDouble,您可以这样做:
class FinTrans {
final private AtomicDouble amount = new AtomicDouble();
public void debit(double debit) {
double current = 0;
double new = 0;
do {
current = amount.get();
new = current + debit;
} while (!amount.compareAndSet(current, newAmount));
}
public void credit(double credit) {
debit(- credit);
}
}https://stackoverflow.com/questions/27519301
复制相似问题