From 488bc1d313b3ec6efa6f619ad80795ecac34b4f2 Mon Sep 17 00:00:00 2001 From: mishadoff Date: Tue, 29 Oct 2013 02:46:18 +0200 Subject: [PATCH] More testing --- src/concurrency/stm/Ref.java | 17 +++++++++- src/concurrency/test/Account.java | 8 ++--- src/concurrency/test/Bank.java | 37 +++++----------------- src/concurrency/test/BankThread.java | 10 +++--- src/concurrency/test/NonSyncStrategy.java | 12 +++++++ src/concurrency/test/RefTest.java | 4 ++- src/concurrency/test/Runner.java | 23 ++++++++++---- src/concurrency/test/STMStrategy.java | 24 ++++++++++++++ src/concurrency/test/SyncStrategy.java | 12 +++++++ src/concurrency/test/TransferStrategy.java | 8 +++++ 10 files changed, 108 insertions(+), 47 deletions(-) create mode 100644 src/concurrency/test/NonSyncStrategy.java create mode 100644 src/concurrency/test/STMStrategy.java create mode 100644 src/concurrency/test/SyncStrategy.java create mode 100644 src/concurrency/test/TransferStrategy.java diff --git a/src/concurrency/stm/Ref.java b/src/concurrency/stm/Ref.java index 58bc211..037d475 100644 --- a/src/concurrency/stm/Ref.java +++ b/src/concurrency/stm/Ref.java @@ -7,7 +7,7 @@ public final class Ref { RefTuple content; public Ref(T value) { - content = RefTuple.get(value, 0); + content = RefTuple.get(value, 0L); } public T getValue(Context ctx) { @@ -17,4 +17,19 @@ public T getValue(Context ctx) { public void setValue(T value, Transaction tx) { tx.set(this, value); } + + /* + UNSAFE + ONLY FOR INSTRUMENTATION + */ + + @Deprecated + public T get() { + return content.value; + } + + @Deprecated + public void set(T value) { + this.content.value = value; + } } diff --git a/src/concurrency/test/Account.java b/src/concurrency/test/Account.java index 851f1ff..c26ab56 100644 --- a/src/concurrency/test/Account.java +++ b/src/concurrency/test/Account.java @@ -3,20 +3,18 @@ import concurrency.stm.Ref; public class Account { - private long money; private Ref moneyRef; Account(long initialMoney) { - money = initialMoney; - moneyRef = new Ref(money); + moneyRef = new Ref(initialMoney); } public void add(long amount) { - money += amount; + moneyRef.set(moneyRef.get() + amount); } long getMoney() { - return money; + return moneyRef.get(); } public Ref getRef() { diff --git a/src/concurrency/test/Bank.java b/src/concurrency/test/Bank.java index 40de61e..11b61bc 100644 --- a/src/concurrency/test/Bank.java +++ b/src/concurrency/test/Bank.java @@ -8,36 +8,21 @@ import java.util.concurrent.TimeUnit; public class Bank { - private Account[] accounts; + Account[] accounts; private Random random = new Random(); + long total = 0; + double charge = 0; + public Bank() { randomFill(); } - synchronized void transfer(Account a1, Account a2, int amount) { - a1.add(-amount); - a2.add(amount); - } - - void transferSTM(final Account a1, final Account a2, final int value) { - STM.transaction(new TransactionBlock() { - @Override - public void run() { - Transaction tx = this.getTx(); - long old1 = a1.getRef().getValue(tx); - a1.getRef().setValue(old1 - value, tx); - long old2 = a2.getRef().getValue(tx); - a2.getRef().setValue(old2 + value, tx); - } - }); - } - private void randomFill() { int NUM = 100; accounts = new Account[NUM]; for (int i = 0; i < NUM; i++) { - accounts[i] = new Account(10000); + accounts[i] = new Account(100000); } } @@ -46,7 +31,7 @@ public Account getRandomAccount() { } public int getRandomValue() { - return random.nextInt(10); + return random.nextInt(100); } public long sum() { @@ -55,17 +40,11 @@ public long sum() { return sum; } - public long sumSTM() { - long sum = 0; - for (Account a : accounts) sum += a.getRef().getValue(GlobalContext.get()); - return sum; - } - - public void simulate(int threads, int num) throws Exception{ + public void simulate(int threads, int num, TransferStrategy ts) throws Exception{ ExecutorService service = Executors.newFixedThreadPool(threads); for (int i = 0; i < threads; i++) { - service.submit(new BankThread(this, num)); + service.submit(new BankThread(this, num, ts)); } service.shutdown(); service.awaitTermination(1, TimeUnit.MINUTES); diff --git a/src/concurrency/test/BankThread.java b/src/concurrency/test/BankThread.java index b9c9314..3cabde7 100644 --- a/src/concurrency/test/BankThread.java +++ b/src/concurrency/test/BankThread.java @@ -3,18 +3,20 @@ public class BankThread implements Runnable { private Bank bank; private int num; + private TransferStrategy ts; - public BankThread(Bank bank, int num) { + public BankThread(Bank bank, int num, TransferStrategy ts) { this.bank = bank; this.num = num; + this.ts = ts; } @Override public void run() { for (int i = 0; i < num; i++) { - bank.transferSTM(bank.getRandomAccount(), - bank.getRandomAccount(), - bank.getRandomValue()); + ts.transfer(bank.getRandomAccount(), + bank.getRandomAccount(), + bank.getRandomValue()); } } } diff --git a/src/concurrency/test/NonSyncStrategy.java b/src/concurrency/test/NonSyncStrategy.java new file mode 100644 index 0000000..66e3d98 --- /dev/null +++ b/src/concurrency/test/NonSyncStrategy.java @@ -0,0 +1,12 @@ +package concurrency.test; + +/** + * @author mishadoff + */ +public class NonSyncStrategy implements TransferStrategy { + @Override + public void transfer(Account a, Account b, int amount) { + a.add(-amount); + b.add(amount); + } +} diff --git a/src/concurrency/test/RefTest.java b/src/concurrency/test/RefTest.java index bfae315..b47aea1 100644 --- a/src/concurrency/test/RefTest.java +++ b/src/concurrency/test/RefTest.java @@ -12,7 +12,9 @@ public static void main(String[] args) { Bank bank = new Bank(); - bank.transferSTM(a, b, 10); + new STMStrategy().transfer(a, b, 10); + new STMStrategy().transfer(a, b, 10); + new STMStrategy().transfer(a, b, 10); System.out.println("A: " + a.getRef().getValue(GlobalContext.get())); System.out.println("B: " + b.getRef().getValue(GlobalContext.get())); diff --git a/src/concurrency/test/Runner.java b/src/concurrency/test/Runner.java index 19cf075..14c623f 100644 --- a/src/concurrency/test/Runner.java +++ b/src/concurrency/test/Runner.java @@ -2,12 +2,21 @@ public class Runner { public static void main(String[] args) throws Exception{ - Bank bank = new Bank(); - System.out.println("Bank sum before: " + bank.sumSTM()); - long before = System.currentTimeMillis(); - bank.simulate(10, 100000); - long after = System.currentTimeMillis(); - System.out.println("Bank sum after: " + bank.sumSTM()); - System.out.println("Elapsed time: " + (after - before)); + TransferStrategy[] tss = new TransferStrategy[] { + new NonSyncStrategy(), + new SyncStrategy(), + new STMStrategy() + }; + + for (TransferStrategy ts : tss) { + Bank bank = new Bank(); + System.out.println(ts.getClass().getSimpleName()); + System.out.println("Bank sum before: " + bank.sum()); + long before = System.currentTimeMillis(); + bank.simulate(100, 10000, ts); + long after = System.currentTimeMillis(); + System.out.println("Bank sum after: " + bank.sum()); + System.out.println("Elapsed time: " + (after - before)); + } } } diff --git a/src/concurrency/test/STMStrategy.java b/src/concurrency/test/STMStrategy.java new file mode 100644 index 0000000..764d25f --- /dev/null +++ b/src/concurrency/test/STMStrategy.java @@ -0,0 +1,24 @@ +package concurrency.test; + +import concurrency.stm.STM; +import concurrency.stm.Transaction; +import concurrency.stm.TransactionBlock; + +/** + * @author mishadoff + */ +public class STMStrategy implements TransferStrategy { + @Override + public void transfer(final Account a, final Account b, final int amount) { + STM.transaction(new TransactionBlock() { + @Override + public void run() { + Transaction tx = this.getTx(); + long old1 = a.getRef().getValue(tx); + a.getRef().setValue(old1 - amount, tx); + long old2 = b.getRef().getValue(tx); + b.getRef().setValue(old2 + amount, tx); + } + }); + } +} diff --git a/src/concurrency/test/SyncStrategy.java b/src/concurrency/test/SyncStrategy.java new file mode 100644 index 0000000..e16228f --- /dev/null +++ b/src/concurrency/test/SyncStrategy.java @@ -0,0 +1,12 @@ +package concurrency.test; + +/** + * @author mishadoff + */ +public class SyncStrategy implements TransferStrategy{ + @Override + public synchronized void transfer(Account a, Account b, int amount) { + a.add(-amount); + b.add(amount); + } +} diff --git a/src/concurrency/test/TransferStrategy.java b/src/concurrency/test/TransferStrategy.java new file mode 100644 index 0000000..908cc5a --- /dev/null +++ b/src/concurrency/test/TransferStrategy.java @@ -0,0 +1,8 @@ +package concurrency.test; + +/** + * @author mishadoff + */ +public interface TransferStrategy { + void transfer(final Account a, final Account b, final int amount); +}