Mam taki programik:
public class Main {
public static void main(String[] args) {
ExecutorService ex = Executors.newFixedThreadPool(5);
Account accountFrom = new Account(10);
Account accountTo = new Account(5);
ex.execute(new AccountTask(accountFrom, accountTo));
ex.execute(new AccountTask(accountFrom, accountTo));
ex.execute(new AccountTask(accountFrom, accountTo));
}
}
public class Account {
private int amount;
public Account(int amount) {
this.amount = amount;
}
public void add(int i) {
amount += i;
}
public void reduce(int i) {
amount -= i;
}
public int getAmount() {
return amount;
}
@Override
public String toString() {
return "amount=" + amount;
}
}
public class AccountTask implements Runnable{
private Account accountFrom;
private Account accountTo;
AtomicInteger counter = new AtomicInteger(1);
public AccountTask(Account accountFrom, Account accountTo) {
this.accountFrom = accountFrom;
this.accountTo = accountTo;
}
@Override
public void run() {
while(true) {
synchronized(this) {
int amo = counter.incrementAndGet();
accountFrom.reduce(amo);
accountTo.add(amo);
accountTo.reduce(amo);
accountFrom.add(amo);
if(accountFrom.getAmount() != 10 || accountTo.getAmount() != 5) {
System.out.println(amo + " " + accountFrom + " " + accountTo);
break;
}
}
}
}
}
Po uruchomieniu zawsze udaje mu się wejść do:
if(accountFrom.getAmount() != 10 || accountTo.getAmount() != 5) {
System.out.println(amo + " " + accountFrom + " " + accountTo);
break;
}
pomimo moich nalegań, żeby tego nie robił:
synchronized(this)
Pytanie dlaczego on mi to czyni? W założeniu do obu stron dodaję i odejmuję tyle samo więc ten if nie powinien być osiągalny.