parentQueue) {
33 | this.actorMessages = actorMessages;
34 | this.parentQueue = parentQueue;
35 | }
36 |
37 | @Override
38 | public void run() {
39 | boolean process = true;
40 | while (process) {
41 | try {
42 | ActorMessage msg = actorMessages.poll(5, TimeUnit.MILLISECONDS);
43 | if (msg == null) {
44 | if (actor != null) {
45 | //System.out.println("Ready...");
46 | parentQueue.put(new ActorMessage(ActorMessage.WORKER_IS_READY, actor, null, null));
47 | actor = null;
48 | }
49 | msg = actorMessages.take();
50 | }
51 |
52 | if (ActorMessage.METHOD_CALL.equals(msg.getType())) {
53 | Method m = msg.getMethod();
54 | actor = msg.getActor();
55 | Object invoke = m.invoke(actor, msg.getArgs());
56 | }
57 | else
58 | if (ActorMessage.POISON_PILL.equals(msg.getType())) {
59 | System.out.println("Poison pill received... Shutting down the actor's thread");
60 | process = false;
61 | }
62 |
63 | } catch (InterruptedException e) {
64 | throw new RuntimeException(e);
65 | } catch (IllegalAccessException e) {
66 | throw new RuntimeException(e);
67 | } catch (InvocationTargetException e) {
68 | throw new RuntimeException(e);
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/eightstations/Railway.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.eightstations;
2 |
3 | import java.util.concurrent.atomic.AtomicInteger;
4 |
5 | /**
6 | * @author Aliaksei Papou
7 | * @since 23.11.13
8 | */
9 | public class Railway {
10 |
11 | private final int stationCount;
12 | private final Train[] train;
13 | private final AtomicInteger[] stationIndex;
14 |
15 | public Railway(int trainCount, int trainCapacity, int stationCount) {
16 | this.stationCount = stationCount;
17 | stationIndex = new AtomicInteger[trainCount];
18 | train = new Train[trainCount];
19 | for (int i = 0; i < trainCount; i++) {
20 | stationIndex[i] = new AtomicInteger();
21 | train[i] = new Train(trainCapacity);
22 | }
23 | }
24 |
25 | public Train waitTrainOnStation(final int trainNo, final int stationNo) {
26 | while (stationIndex[trainNo].get() % stationCount != stationNo) {
27 | Thread.yield();
28 | }
29 | return train[trainNo];
30 | }
31 |
32 | public void sendTrain(final int trainNo) {
33 | stationIndex[trainNo].getAndIncrement();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/eightstations/RailwayTest.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.eightstations;
2 |
3 | /**
4 | *
5 | * @author Aliaksei Papou
6 | * @since 23.11.13
7 | */
8 | public class RailwayTest {
9 |
10 | public static void main(String[] args) {
11 | new RailwayTest().testRailWay();
12 | }
13 |
14 | public void testRailWay() {
15 | final int stationCount = 8;
16 | final int trainCount = 32;
17 | final int trainCapacity = 256;
18 |
19 | final Railway railway = new Railway(trainCount, trainCapacity, stationCount);
20 |
21 | final long n = 20000000000l;
22 |
23 | for (int i = 1; i < stationCount; i++) {
24 |
25 | final int stationNo = i;
26 | new Thread() {
27 | long lastValue = 0;
28 |
29 | @Override
30 | public void run() {
31 | int trainIndex = 0;
32 | while (lastValue < n) {
33 | final int trainNo = trainIndex % trainCount;
34 |
35 | Train train = railway.waitTrainOnStation(trainNo, stationNo);
36 | int count = train.getCapacity() / (stationCount - 1);
37 | for (int i = 0; i < count; i++) {
38 | lastValue = train.getGoods(i);
39 | }
40 | railway.sendTrain(trainNo);
41 |
42 | trainIndex++;
43 | }
44 | }
45 | }.start();
46 |
47 | }
48 | final long start = System.nanoTime();
49 |
50 | long i = 0;
51 | int trainIndex = 0;
52 | while (i < n) {
53 | final int trainNo = trainIndex % trainCount;
54 |
55 | Train train = railway.waitTrainOnStation(trainNo, 0);
56 | int capacity = train.getCapacity() - train.goodsCount();
57 |
58 | for (int j = 0; j < capacity; j++) {
59 | train.addGoods((int)i++);
60 | }
61 | railway.sendTrain(trainNo);
62 |
63 | trainIndex++;
64 |
65 | if (i % 10000000 == 0) {
66 | final long duration = System.nanoTime() - start;
67 |
68 | final long ops = (i * 1000L * 1000L * 1000L) / duration;
69 | System.out.format("ops/sec = %,d\n", ops);
70 | System.out.format("trains/sec = %,d\n", ops / trainCapacity);
71 | System.out.format("latency nanos = %.1f%n\n", duration / (float)(i) * (float) trainCapacity);
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/eightstations/Train.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.eightstations;
2 |
3 | /**
4 | * @author Aliaksei Papou
5 | * @since 23.11.13
6 | */
7 | public class Train {
8 |
9 | private final long[] goodsArray;
10 | private int index;
11 | private int trainCapacity;
12 |
13 | public Train(int trainCapacity) {
14 | this.trainCapacity = trainCapacity;
15 | goodsArray = new long[trainCapacity];
16 | }
17 |
18 | public int goodsCount() {
19 | return index;
20 | }
21 |
22 | public void addGoods(long i) {
23 | goodsArray[index++] = i;
24 | }
25 |
26 | public long getGoods(int i) {
27 | index--;
28 | return goodsArray[i];
29 | }
30 |
31 | public int getCapacity() {
32 | return trainCapacity;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/lotoftrains/Railway.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.lotoftrains;
2 |
3 |
4 | import java.util.concurrent.atomic.AtomicInteger;
5 |
6 | /**
7 | * @author Aliaksei Papou
8 | * @since 23.11.13
9 | */
10 | public class Railway {
11 |
12 | private final int stationCount = 2;
13 | private final Train[] train;
14 | private final AtomicInteger[] stationIndex;
15 |
16 | public Railway(int trainCount, int trainCapacity) {
17 | stationIndex = new AtomicInteger[trainCount];
18 | train = new Train[trainCount];
19 | for (int i = 0; i < trainCount; i++) {
20 | stationIndex[i] = new AtomicInteger();
21 | train[i] = new Train(trainCapacity);
22 | }
23 | }
24 |
25 | public Train waitTrainOnStation(final int trainNo, final int stationNo) {
26 | while (stationIndex[trainNo].get() % stationCount != stationNo) {
27 | Thread.yield();
28 | }
29 | return train[trainNo];
30 | }
31 |
32 | public void sendTrain(final int trainNo) {
33 | stationIndex[trainNo].getAndIncrement();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/lotoftrains/RailwayTest.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.lotoftrains;
2 |
3 |
4 | /**
5 | *
6 | * @author Aliaksei Papou
7 | * @since 23.11.13
8 | */
9 | public class RailwayTest {
10 |
11 | public static void main(String[] args) {
12 | new RailwayTest().testRailWay();
13 | }
14 |
15 | public void testRailWay() {
16 | final int trainCount = 256;
17 | final int trainCapacity = 128;
18 |
19 | final Railway railway = new Railway(trainCount, trainCapacity);
20 |
21 | final long n = 20000000000l;
22 |
23 | new Thread() {
24 | long lastValue = 0;
25 |
26 | @Override
27 | public void run() {
28 | int trainIndex = 0;
29 | while (lastValue < n) {
30 | final int trainNo = trainIndex % trainCount;
31 |
32 | Train train = railway.waitTrainOnStation(trainNo, 1);
33 | int count = train.goodsCount();
34 | for (int i = 0; i < count; i++) {
35 | lastValue = train.getGoods(i);
36 | }
37 | railway.sendTrain(trainNo);
38 |
39 | trainIndex++;
40 | }
41 | }
42 | }.start();
43 |
44 | final long start = System.nanoTime();
45 |
46 | long i = 0;
47 | int trainIndex = 0;
48 | while (i < n) {
49 | final int trainNo = trainIndex % trainCount;
50 |
51 | Train train = railway.waitTrainOnStation(trainNo, 0);
52 | int capacity = train.getCapacity();
53 | for (int j = 0; j < capacity; j++) {
54 | train.addGoods((int)i++);
55 | }
56 | railway.sendTrain(trainNo);
57 |
58 | trainIndex++;
59 |
60 | if (i % 1000000000 == 0) {
61 | final long duration = System.nanoTime() - start;
62 |
63 | final long ops = (i * 1000L * 1000L * 1000L) / duration;
64 | System.out.format("ops/sec = %,d\n", ops);
65 | System.out.format("trains/sec = %,d\n", ops / trainCapacity);
66 | System.out.format("latency nanos = %.1f%n\n", duration / (float)(i) * (float) trainCapacity);
67 |
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/lotoftrains/Train.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.lotoftrains;
2 |
3 | /**
4 | * @author Aliaksei Papou
5 | * @since 23.11.13
6 | */
7 | public class Train {
8 |
9 | private final long[] goodsArray;
10 | private int index;
11 | private int trainCapacity;
12 |
13 | public Train(int trainCapacity) {
14 | this.trainCapacity = trainCapacity;
15 | goodsArray = new long[trainCapacity];
16 | }
17 |
18 |
19 | public int goodsCount() {
20 | return index;
21 | }
22 |
23 | public void addGoods(long i) {
24 | goodsArray[index++] = i;
25 | }
26 |
27 | public long getGoods(int i) {
28 | index--;
29 | return goodsArray[i];
30 | }
31 |
32 | public int getCapacity() {
33 | return trainCapacity;
34 | }
35 |
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/mpsclatency/Railway.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.mpsclatency;
2 |
3 | import java.util.concurrent.atomic.AtomicInteger;
4 |
5 | /**
6 | * @author Aliaksei Papou
7 | * @since 23.11.13
8 | */
9 | @SuppressWarnings("unused")
10 | public class Railway {
11 |
12 | private final int mask;
13 | private final Train[] train;
14 |
15 | public Railway(int trainCount, int trainCapacity, int stationCount) {
16 | mask = stationCount - 1;
17 | train = new Train[trainCount];
18 | for (int i = 0; i < trainCount; i++) {
19 | train[i] = new Train(trainCapacity);
20 | }
21 | }
22 |
23 | public Train waitTrainOnStation(final int trainNo, final int stationNo) {
24 | while ((train[trainNo].stationIndex.get() & mask) != stationNo) {
25 | Thread.yield();
26 | }
27 | return train[trainNo];
28 | }
29 |
30 | public void sendTrain(final int trainNo) {
31 | final AtomicInteger stationIndex = train[trainNo].stationIndex;
32 | stationIndex.lazySet(stationIndex.get() + 1);
33 | }
34 |
35 | public void sendTrainToStation(int trainNo, int stationNo) {
36 | train[trainNo].stationIndex.set(stationNo);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/mpsclatency/ThreeProducersOneConsumerRailwayTest.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.mpsclatency;
2 |
3 | import java.util.Locale;
4 |
5 | /**
6 | *
7 | * This test shows a case with 3 producers and 1 consumer (3P:1C).
8 | *
9 | * The railway uses 65536 trains with capacity 3.
10 | * Trains go sequentially from one station (thread) to another.
11 | *
12 | * +----+
13 | * | P1 |------+
14 | * +----+ |
15 | * v
16 | * +----+ +----+
17 | * | P2 |--->| C1 |
18 | * +----+ +----+
19 | * ^
20 | * +----+ |
21 | * | P3 |------+
22 | * +----+
23 | *
24 | * For tests the following processor has been used:
25 | * Intel® Core™ i7-3632QM Processor (6M Cache, up to 3.20 GHz) BGA with 4 Cores
26 | * http://ark.intel.com/products/71670/Intel-Core-i7-3632QM-Processor-6M-Cache-up-to-3_20-GHz-BGA
27 | *
28 | * After some warming up of the CPU up to 3.20 GHz the following results achieved:
29 | *
30 | * Railway average test results
31 | * ops/sec = 206,937,353
32 | * trains/sec = 68,979,117
33 | * latency ns = 14.5
34 | *
35 | * The best result achieved:
36 | * ops/sec = 296,305,364
37 | * trains/sec = 98,768,454
38 | * latency ns = 10.1
39 | *
40 | *
41 | * To fill the difference the following results on the same hardware show Disruptor test for the same 3P:1C
42 | * https://github.com/LMAX-Exchange/disruptor/blob/master/src/perftest/java/com/lmax/disruptor/ThreePublisherToOneProcessorSequencedThroughputTest.java
43 | *
44 | * Starting Queue tests
45 | * Run 0, BlockingQueue=4,353,504 ops/sec
46 | * Run 1, BlockingQueue=4,353,504 ops/sec
47 | * Run 2, BlockingQueue=4,328,067 ops/sec
48 | * Run 3, BlockingQueue=4,316,857 ops/sec
49 | * Starting Disruptor tests
50 | * Run 0, Disruptor=11,467,889 ops/sec
51 | * Run 1, Disruptor=11,280,315 ops/sec
52 | * Run 2, Disruptor=11,286,681 ops/sec
53 | * Run 3, Disruptor=11,254,924 ops/sec
54 | *
55 | * Below the results of running 3P:1C test with batching (10 items per a batch):
56 | * https://github.com/LMAX-Exchange/disruptor/blob/master/src/perftest/java/com/lmax/disruptor/ThreePublisherToOneProcessorBatchThroughputTest.java
57 | *
58 | * Starting Queue tests
59 | * Run 0, BlockingQueue=4,546,281 ops/sec
60 | * Run 1, BlockingQueue=4,508,769 ops/sec
61 | * Run 2, BlockingQueue=4,101,386 ops/sec
62 | * Run 3, BlockingQueue=4,124,561 ops/sec
63 | * Starting Disruptor tests
64 | * Run 0, Disruptor=116,009,280 ops/sec
65 | * Run 1, Disruptor=128,205,128 ops/sec
66 | * Run 2, Disruptor=101,317,122 ops/sec
67 | * Run 3, Disruptor=98,716,683 ops/sec
68 | *
69 | * Summary
70 | *
71 | * The Best Results:
72 | * Railway = 296,305,364 ops/sec
73 | * Disruptor = 128,205,128 ops/sec
74 | * BlockingQueue = 4,546,281 ops/sec
75 | *
76 | *
77 | * @author Aliaksei Papou
78 | * @since 23.11.13
79 | */
80 | public class ThreeProducersOneConsumerRailwayTest {
81 |
82 | public static void main(String[] args) {
83 | new ThreeProducersOneConsumerRailwayTest().testRailWay();
84 | }
85 |
86 | public void testRailWay() {
87 | Locale.setDefault(Locale.US);
88 | final int stationCount = 4;
89 | final int trainCount = 64 * 1024;
90 | final int mask = trainCount - 1;
91 | final int lastStationNo = stationCount - 1;
92 | final short trainCapacity = (stationCount - 1) ;
93 |
94 | final Railway railway = new Railway(trainCount, trainCapacity, stationCount);
95 |
96 | final long n = 20l * 1000 * 1000 * 1000;
97 |
98 | // starting producers
99 | for (int i = 0; i < lastStationNo; i++) {
100 |
101 | final int stationNo = i;
102 | new Thread() {
103 | long lastValue = 0;
104 |
105 | @Override
106 | public void run() {
107 | long trainIndex = 0;
108 | while (lastValue < n) {
109 | final int trainNo = (int) (trainIndex & mask);
110 |
111 | Train train = railway.waitTrainOnStation(trainNo, stationNo);
112 | int count = train.getCapacity() / trainCapacity;
113 | for (int i = 0; i < count; i++) {
114 | train.addGoods(trainIndex);
115 | }
116 |
117 | railway.sendTrain(trainNo);
118 |
119 | trainIndex++;
120 | }
121 | }
122 | }.start();
123 |
124 | }
125 | final long start = System.nanoTime();
126 |
127 | long i = 0;
128 | long trainIndex = 0;
129 |
130 | while (i < n) {
131 | final int trainNo = (int) (trainIndex & mask);
132 |
133 | Train train = railway.waitTrainOnStation(trainNo, lastStationNo);
134 | int goodsCount = train.goodsCount();
135 |
136 | long goods;
137 |
138 | for (int j = 0; j < goodsCount; j++) {
139 | goods = train.getGoods(j);
140 | i++;
141 | }
142 | railway.sendTrain(trainNo);
143 |
144 | trainIndex++;
145 |
146 | if ((trainIndex % 100000000) == 0) {
147 | final long duration = System.nanoTime() - start;
148 |
149 | final long ops = (i * 1000L * 1000L * 1000L) / duration;
150 | System.out.format("ops/sec = %,d\n", ops);
151 | System.out.format("trains/sec = %,d\n", ops / trainCapacity);
152 | System.out.format("latency ns = %.1f%n\n", duration / (float) (i) * (float) trainCapacity);
153 | }
154 | }
155 |
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/mpsclatency/Train.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.mpsclatency;
2 |
3 | import java.util.concurrent.atomic.AtomicInteger;
4 |
5 | /**
6 | * @author Aliaksei Papou
7 | * @since 23.11.13
8 | */
9 | public class Train {
10 |
11 | private static int trainCapacity;
12 | private final long[] goodsArray;
13 | public AtomicInteger stationIndex = new AtomicInteger();
14 | private int index;
15 |
16 | public Train(int trainCapacity) {
17 | this.trainCapacity = trainCapacity;
18 | goodsArray = new long[trainCapacity];
19 | }
20 |
21 | public int goodsCount() {
22 | return index;
23 | }
24 |
25 | public void addGoods(long i) {
26 | goodsArray[index++] = i;
27 | }
28 |
29 | public long getGoods(int i) {
30 | index--;
31 | return goodsArray[i];
32 | }
33 |
34 | public int getCapacity() {
35 | return trainCapacity;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/onetrain/RailWay.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.onetrain;
2 |
3 | import java.util.concurrent.atomic.AtomicInteger;
4 |
5 | /**
6 | * @author Aliaksei Papou
7 | * @since 23.11.13
8 | */
9 | public class Railway {
10 |
11 | private final int stationCount = 2;
12 | private final Train train = new Train();
13 | private final AtomicInteger stationIndex = new AtomicInteger();
14 |
15 | public Train waitTrainOnStation(final int stationNo) {
16 | while (stationIndex.get() % stationCount != stationNo) {
17 | Thread.yield();
18 | }
19 | return train;
20 | }
21 | public void sendTrain() {
22 | stationIndex.getAndIncrement();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/onetrain/RailWayTest.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.onetrain;
2 |
3 | /**
4 | *
5 | * @author Aliaksei Papou
6 | * @since 23.11.13
7 | */
8 | public class RailwayTest {
9 | public static void main(String[] args) {
10 | new RailwayTest().testRailWay();
11 | }
12 |
13 | public void testRailWay() {
14 | final Railway railway = new Railway();
15 |
16 | final long n = 20000000000l;
17 |
18 | new Thread() {
19 | long lastValue = 0;
20 |
21 | @Override
22 | public void run() {
23 |
24 | while (lastValue < n) {
25 | Train train = railway.waitTrainOnStation(1);
26 | int count = train.goodsCount();
27 | for (int i = 0; i < count; i++) {
28 | lastValue = train.getGoods(i);
29 | }
30 | railway.sendTrain();
31 | }
32 | }
33 | }.start();
34 |
35 | final long start = System.nanoTime();
36 |
37 | long i = 0;
38 | while (i < n) {
39 | Train train = railway.waitTrainOnStation(0);
40 | int capacity = train.getCapacity();
41 | for (int j = 0; j < capacity; j++) {
42 | train.addGoods((int)i++);
43 | }
44 | railway.sendTrain();
45 |
46 | if (i % 1000000 == 0) {
47 | final long duration = System.nanoTime() - start;
48 |
49 | final long ops = (i * 1000L * 1000L * 1000L) / duration;
50 | System.out.format("ops/sec = %,d\n", ops);
51 | System.out.format("trains/sec = %,d\n", ops / Train.CAPACITY);
52 | System.out.format("latency nanos = %.3f%n\n", duration / (float)(i) * (float) Train.CAPACITY);
53 |
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/onetrain/Train.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.onetrain;
2 |
3 | /**
4 | * @author Aliaksei Papou
5 | * @since 23.11.13
6 | */
7 | public class Train {
8 |
9 | public static int CAPACITY = 2*1024;
10 |
11 | private final long[] goodsArray = new long[CAPACITY];
12 |
13 | private int index;
14 |
15 | public int goodsCount() {
16 | return index;
17 | }
18 |
19 | public void addGoods(long i) {
20 | goodsArray[index++] = i;
21 | }
22 |
23 | public long getGoods(int i) {
24 | index--;
25 | return goodsArray[i];
26 | }
27 |
28 | public int getCapacity() {
29 | return CAPACITY;
30 | }
31 |
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/singlethread/SingleThread.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.singlethread;
2 |
3 | import java.util.Locale;
4 |
5 | /**
6 | * @author Aliaksei Papou
7 | * @since 18.11.13
8 | */
9 | public class SingleThread {
10 |
11 | private static final long ITERATIONS = 1000L * 1000L * 50L;
12 |
13 | public static void main(String[] args) {
14 | Locale.setDefault(Locale.US);
15 | new SingleThread();
16 | }
17 |
18 | public SingleThread() {
19 | final long start = System.nanoTime();
20 |
21 | long i = 0;
22 | while (i < ITERATIONS) {
23 | i++;
24 | }
25 |
26 | final long duration = System.nanoTime() - start;
27 |
28 | final long ops = (ITERATIONS * 1000L * 1000L * 1000L) / duration;
29 | System.out.format("ops/sec = %,d\n", ops);
30 | System.out.format("latency ns = %.3f%n", duration / (float)(ITERATIONS) );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/twotrains/Railway.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.twotrains;
2 |
3 | import java.util.concurrent.atomic.AtomicInteger;
4 |
5 | /**
6 | * @author Aliaksei Papou
7 | * @since 23.11.13
8 | */
9 | public class Railway {
10 |
11 | private final int stationCount = 2;
12 | private final Train[] train = new Train[]{
13 | new Train(),
14 | new Train(),
15 | };
16 |
17 | private final AtomicInteger[] stationIndex = new AtomicInteger[]{
18 | new AtomicInteger(0),
19 | new AtomicInteger(0),
20 | };
21 |
22 | public Train waitTrainOnStation(final int trainNo, final int stationNo) {
23 | while (stationIndex[trainNo].get() % stationCount != stationNo) {
24 | Thread.yield();
25 | }
26 | return train[trainNo];
27 | }
28 |
29 | public void sendTrain(final int trainNo) {
30 | stationIndex[trainNo].getAndIncrement();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/twotrains/RailwayTest.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.twotrains;
2 |
3 | /**
4 | *
5 | * @author Aliaksei Papou
6 | * @since 23.11.13
7 | */
8 | public class RailwayTest {
9 |
10 | public static void main(String[] args) {
11 | new RailwayTest().testRailWay();
12 | }
13 |
14 | public void testRailWay() {
15 | final Railway railway = new Railway();
16 |
17 | final long n = 20000000000l;
18 |
19 | new Thread() {
20 | long lastValue = 0;
21 |
22 | @Override
23 | public void run() {
24 | int trainIndex = 0;
25 | while (lastValue < n) {
26 | final int trainNo = trainIndex % 2;
27 |
28 | Train train = railway.waitTrainOnStation(trainNo, 1);
29 | int count = train.goodsCount();
30 | for (int i = 0; i < count; i++) {
31 | lastValue = train.getGoods(i);
32 | }
33 | railway.sendTrain(trainNo);
34 |
35 | trainIndex++;
36 | }
37 | }
38 | }.start();
39 |
40 | final long start = System.nanoTime();
41 |
42 | long i = 0;
43 | int trainIndex = 0;
44 | while (i < n) {
45 | final int trainNo = trainIndex % 2;
46 |
47 | Train train = railway.waitTrainOnStation(trainNo, 0);
48 | int capacity = train.getCapacity();
49 | for (int j = 0; j < capacity; j++) {
50 | train.addGoods((int)i++);
51 | }
52 | railway.sendTrain(trainNo);
53 |
54 | trainIndex++;
55 |
56 | if (i % 10000000 == 0) {
57 | final long duration = System.nanoTime() - start;
58 |
59 | final long ops = (i * 1000L * 1000L * 1000L) / duration;
60 | System.out.format("ops/sec = %,d\n", ops);
61 | System.out.format("trains/sec = %,d\n", ops / Train.CAPACITY);
62 | System.out.format("latency nanos = %.1f%n\n", duration / (float)(i) * (float) Train.CAPACITY);
63 |
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/twotrains/Train.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.twotrains;
2 |
3 | /**
4 | * @author Aliaksei Papou
5 | * @since 23.11.13
6 | */
7 | public class Train {
8 |
9 | public static int CAPACITY = 32768;
10 |
11 | private final long[] goodsArray = new long[CAPACITY];
12 |
13 | private int index;
14 |
15 | public int goodsCount() {
16 | return index;
17 | }
18 |
19 | public void addGoods(long i) {
20 | goodsArray[index++] = i;
21 | }
22 |
23 | public long getGoods(int i) {
24 | index--;
25 | return goodsArray[i];
26 | }
27 |
28 | public int getCapacity() {
29 | return CAPACITY;
30 | }
31 |
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/ultrahighthroughput/RailWay.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.ultrahighthroughput;
2 |
3 | import java.util.concurrent.atomic.AtomicLong;
4 |
5 | /**
6 | * User: APOPOV
7 | * Date: 05.12.13
8 | */
9 | public class RailWay {
10 |
11 | public static int TRAIN_COUNT = 8;
12 | private AtomicLong[] trainNoLong;
13 |
14 | private final Train[] train;
15 |
16 | private final int capacity;
17 | private final int mask;
18 |
19 | public RailWay(final int stationCount, int trainCapacity, int trainCount) {
20 | TRAIN_COUNT = trainCount;
21 | trainNoLong = new AtomicLong[trainCount];
22 | train = new Train[trainCount];
23 | for (int i = 0; i < trainCount; i++) {
24 | train[i] = new Train(trainCapacity);
25 | trainNoLong[i] = new AtomicLong();
26 | }
27 |
28 | capacity = findNextPositivePowerOfTwo(stationCount);
29 | mask = capacity - 1;
30 | }
31 |
32 | public static int findNextPositivePowerOfTwo(final int value) {
33 | return 1 << (32 - Integer.numberOfLeadingZeros(value - 1));
34 | }
35 |
36 | public Train waitTrainOnStation(final int trainIndex, final int stationNo) {
37 | while ((trainNoLong[trainIndex].get() & mask) != stationNo) {
38 | Thread.yield();
39 | }
40 | return train[trainIndex];
41 | }
42 |
43 | public void sendTrain(final int index) {
44 | final AtomicLong atomicLong = trainNoLong[index];
45 | atomicLong.lazySet(atomicLong.get() + 1);
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/ultrahighthroughput/Train.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.ultrahighthroughput;
2 |
3 | /**
4 | * User: APOPOV
5 | * Date: 15.10.13
6 | */
7 | public class Train {
8 |
9 | public static int CAPACITY = 2*1024;
10 |
11 | private final long[] goodsArray;
12 |
13 | private int index;
14 |
15 | public Train(int capacity) {
16 | CAPACITY = capacity;
17 | goodsArray = new long[capacity];
18 | }
19 |
20 | public int getCapacity() {
21 | return CAPACITY;
22 | }
23 |
24 | public void addGoods(long i) {
25 | goodsArray[index++] = i;
26 | }
27 |
28 | public int goodsCount() {
29 | return index;
30 | }
31 |
32 | public long getGoods(int i) {
33 | index--;
34 | return goodsArray[i];
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/api/src/main/java/com/asyncj/core/api/article/ultrahighthroughput/UltraHighThroughputRawRailwayTest.java:
--------------------------------------------------------------------------------
1 | package com.asyncj.core.api.article.ultrahighthroughput;
2 |
3 | import java.util.Locale;
4 |
5 | /**
6 | * User: APOPOV
7 | * Date: 15.10.13
8 | */
9 | public class UltraHighThroughputRawRailwayTest {
10 |
11 | long k = 0;
12 |
13 | public static void main(String[] args) {
14 | new UltraHighThroughputRawRailwayTest();
15 | }
16 |
17 | public UltraHighThroughputRawRailwayTest() {
18 | Locale.setDefault(Locale.US);
19 | final int trainCapacity = 2 * 1024;
20 | final int trainCount = findNextPositivePowerOfTwo(2);
21 | final int stationCount = 2;
22 | final RailWay railWay = new RailWay(stationCount, trainCapacity, trainCount);
23 |
24 | final long n = 20L * 1000 * 1000 * 1000;
25 |
26 | new Thread() {
27 | @Override
28 | public void run() {
29 |
30 | long trainIndex = 0;
31 | final int mask = trainCount - 1;
32 | while (true) {
33 | final int trainNo = (int) (trainIndex & mask);
34 | final Train train = railWay.waitTrainOnStation(trainNo, 1);
35 |
36 | int i = 0;
37 | final int count = train.getCapacity();
38 | while (i < count) {
39 | long j = train.getGoods(i);
40 | i++;
41 | }
42 | railWay.sendTrain(trainNo);
43 |
44 | trainIndex++;
45 | }
46 | }
47 | }.start();
48 |
49 |
50 | int trainIndex = 0;
51 | long i = 0;
52 | final int mask = trainCount - 1;
53 | final long start = System.nanoTime();
54 |
55 | while (i < n) {
56 | final int trainNo = (trainIndex) & mask;
57 | final Train train = railWay.waitTrainOnStation(trainNo, 0);
58 | final int capacity = train.getCapacity();
59 | int j = 0;
60 | while (j < capacity) {
61 | train.addGoods(i++);
62 | j++;
63 | }
64 |
65 | railWay.sendTrain(trainNo);
66 |
67 | trainIndex++;
68 |
69 | if (trainIndex % 1000000 == 0) {
70 | final long duration = System.nanoTime() - start;
71 | final long ops = (i * 1000L * 1000L * 1000L) / duration;
72 | System.out.format("ops/sec = %,d\n", ops);
73 | System.out.format("latency ns = %.3f%n", duration / (float) (i) * (float) trainCapacity);
74 | }
75 | }
76 | }
77 |
78 |
79 | public static int findNextPositivePowerOfTwo(final int value) {
80 | return 1 << (32 - Integer.numberOfLeadingZeros(value - 1));
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/fork/Actor1Impl.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.fork;
17 |
18 | import com.asyncj.core.api.ActorManager;
19 |
20 | class Actor1Impl implements ForkExample.Actor1 {
21 |
22 | private final int workLoad;
23 | int n;
24 | int count = 0;
25 | final long startTime;
26 |
27 | public Actor1Impl(int n) {
28 | this.n = n;
29 | workLoad = this.n / Runtime.getRuntime().availableProcessors();
30 |
31 | startTime = System.currentTimeMillis();
32 | }
33 |
34 | public void pong(ForkExample.Actor2 actor2, String s) {
35 | count++;
36 |
37 | if (count < n - Runtime.getRuntime().availableProcessors()) {
38 | if (count % 100000 == 0)
39 | System.out.println(count + " pings from - " + s);
40 | actor2.ping(this, count);
41 | }
42 | else {
43 | long endTime = System.currentTimeMillis();
44 | System.out.println("super mega total count = " + count + ". In " + (endTime - startTime)/1000 + " seconds");
45 | }
46 | }
47 |
48 | @Override
49 | public void startPings(ActorManager actorManager, int m) {
50 | if (m < workLoad) {
51 | ForkExample.Actor2 actor2 = actorManager.createActor(new Actor2Impl());
52 | actor2.ping(this, m);
53 | }
54 | else {
55 | int m1 = m / 2;
56 | startPings(actorManager, m1);
57 | startPings(actorManager, m - m1);
58 | }
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/fork/Actor2Impl.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.fork;
17 |
18 | class Actor2Impl implements ForkExample.Actor2 {
19 |
20 | public void ping(ForkExample.Actor1 actor1, int count) {
21 | if (count % 100000 == 0)
22 | System.out.println(count + " pongs");
23 | actor1.pong(this, this.toString());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/fork/ForkExample.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.fork;
17 |
18 | import com.asyncj.core.api.ActorManager;
19 | import org.junit.Test;
20 |
21 | /**
22 | * User: APOPOV
23 | * Date: 05.10.13
24 | */
25 | public class ForkExample {
26 |
27 | @Test
28 | public void testPingPong() {
29 |
30 | ActorManager actorManager = new ActorManager();
31 |
32 | int n = 10000000;
33 | Actor1 actor1 = actorManager.createActor(new Actor1Impl(n));
34 |
35 | actor1.startPings(actorManager, n);
36 |
37 | try {
38 | Thread.currentThread().join();
39 | } catch (InterruptedException e) {
40 | throw new RuntimeException(e);
41 | }
42 | }
43 |
44 | public interface Actor1 {
45 | void startPings(ActorManager actorManager, int n);
46 | void pong(Actor2 actor2, String s);
47 | }
48 |
49 | public interface Actor2 {
50 | void ping(Actor1 actor1, int count);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/forkjoin/Actor1Impl.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.forkjoin;
17 |
18 | import com.asyncj.core.api.ActorManager;
19 |
20 | class Actor1Impl implements ForkJoinExample.Actor1 {
21 |
22 | private final int workLoad;
23 | private int n;
24 | private int count = 0;
25 |
26 | private ForkJoinExample.Actor1 parentActor1;
27 | private int incTimes;
28 |
29 | public Actor1Impl(int n, ForkJoinExample.Actor1 parentActor1, int workLoad) {
30 | this.n = n;
31 | this.parentActor1 = parentActor1;
32 | this.workLoad = workLoad;
33 | }
34 |
35 | public void pong(ForkJoinExample.Actor2 actor2, String s) {
36 | count++;
37 |
38 | if (count < n) {
39 | if (count % 100000 == 0)
40 | System.out.println(count + " pings from - " + s);
41 | actor2.ping(this, count);
42 | }
43 | else {
44 | System.out.println("final count = " + count);
45 | if (parentActor1 != null) {
46 | parentActor1.incCount(count);
47 | }
48 | }
49 | }
50 |
51 | @Override
52 | public void incCount(int count) {
53 | incTimes++;
54 | this.count += count;
55 | System.out.println("sub count = " + this.count);
56 | if (incTimes >= 5 && parentActor1 != null) {
57 | parentActor1.incCount(this.count);
58 | }
59 | }
60 |
61 | @Override
62 | public void startPings(ActorManager actorManager, int m) {
63 | if (m < workLoad) {
64 | ForkJoinExample.Actor2 actor2 = actorManager.createActor(new Actor2Impl());
65 | actor2.ping(this, m);
66 | }
67 | else {
68 | int m1 = m / 5;
69 | int m2 = m - m1 * 4;
70 | ForkJoinExample.Actor1 thisActor = actorManager.getReference(this);
71 |
72 | ForkJoinExample.Actor1 actorA = actorManager.createActor(new Actor1Impl(m1, thisActor, workLoad));
73 | ForkJoinExample.Actor1 actorB = actorManager.createActor(new Actor1Impl(m1, thisActor, workLoad));
74 | ForkJoinExample.Actor1 actorC = actorManager.createActor(new Actor1Impl(m1, thisActor, workLoad));
75 | ForkJoinExample.Actor1 actorD = actorManager.createActor(new Actor1Impl(m1, thisActor, workLoad));
76 | ForkJoinExample.Actor1 actorE = actorManager.createActor(new Actor1Impl(m2, thisActor, workLoad));
77 | actorA.startPings(actorManager, m1);
78 | actorB.startPings(actorManager, m1);
79 | actorC.startPings(actorManager, m1);
80 | actorD.startPings(actorManager, m1);
81 | actorE.startPings(actorManager, m2);
82 | }
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/forkjoin/Actor2Impl.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.forkjoin;
17 |
18 | import java.lang.reflect.Proxy;
19 |
20 | class Actor2Impl implements ForkJoinExample.Actor2 {
21 |
22 | public void ping(ForkJoinExample.Actor1 actor1, int count) {
23 | if (count % 100000 == 0)
24 | System.out.println(count + " pongs");
25 | if (!(actor1 instanceof Proxy)) {
26 | throw new RuntimeException("Should be a proxy");
27 | }
28 | actor1.pong(this, this.toString());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/forkjoin/ForkJoinExample.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.forkjoin;
17 |
18 | import com.asyncj.core.api.ActorManager;
19 | import org.junit.Test;
20 |
21 | /**
22 | * User: APOPOV
23 | * Date: 05.10.13
24 | */
25 | public class ForkJoinExample {
26 |
27 | @Test
28 | public void testPingPong() {
29 |
30 | ActorManager actorManager = new ActorManager();
31 |
32 | final long startTime = System.currentTimeMillis();
33 |
34 | int n = 10000000;
35 | int workLoad = n / Runtime.getRuntime().availableProcessors();
36 | Actor1 actor1 = actorManager.createActor(new Actor1Impl(n, new Actor1() {
37 | @Override
38 | public void startPings(ActorManager actorManager, int n) {
39 |
40 | }
41 |
42 | @Override
43 | public void pong(Actor2 actor2, String s) {
44 |
45 | }
46 |
47 | @Override
48 | public void incCount(int count) {
49 | long endTime = System.currentTimeMillis();
50 | System.out.println("super mega total count = " + count + ". In " + (endTime - startTime)/1000 + " seconds");
51 |
52 | }
53 | }, workLoad));
54 |
55 | actor1.startPings(actorManager, n);
56 |
57 | try {
58 | Thread.currentThread().join();
59 | } catch (InterruptedException e) {
60 | throw new RuntimeException(e);
61 | }
62 | }
63 |
64 | public interface Actor1 {
65 | void startPings(ActorManager actorManager, int n);
66 | void pong(Actor2 actor2, String s);
67 |
68 | void incCount(int count);
69 | }
70 |
71 | public interface Actor2 {
72 | void ping(Actor1 actor1, int count);
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/pingpong/Actor1Impl.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.pingpong;
17 |
18 |
19 | import com.asyncj.core.api.ActorManager;
20 |
21 | class Actor1Impl implements PingPongExample.Actor1 {
22 |
23 | int n;
24 | private ActorManager actorManager;
25 | int count = 0;
26 | final long startTime;
27 |
28 |
29 | public Actor1Impl(int i, ActorManager actorManager) {
30 | this.n = i;
31 | this.actorManager = actorManager;
32 | startTime = System.currentTimeMillis();
33 | }
34 |
35 | public void pong(PingPongExample.Actor2 actor2, String s) {
36 | count++;
37 | if (count % 100000 == 0)
38 | System.out.println(count + " pings from - " + s);
39 |
40 | if (count < n) {
41 | actor2.ping(this, count);
42 | }
43 | else {
44 | long endTime = System.currentTimeMillis();
45 | System.out.println("super mega total count = " + count + ". In " + (endTime - startTime)/1000 + " seconds");
46 |
47 | // how to send a final message?
48 | actorManager.unblockResult(this);
49 | }
50 | }
51 |
52 | @Override
53 | public Integer getCount() {
54 | return count;
55 | }
56 |
57 | public void startPings(PingPongExample.Actor2 actor2) {
58 | count++;
59 | actor2.ping(this, count);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/pingpong/Actor2Impl.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.pingpong;
17 |
18 | class Actor2Impl implements PingPongExample.Actor2 {
19 |
20 | public void ping(PingPongExample.Actor1 actor1, int count) {
21 | if (count % 100000 == 0)
22 | System.out.println(count + " pongs");
23 | actor1.pong(this, this.toString());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/pingpong/PingPongExample.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.pingpong;
17 |
18 | import com.asyncj.core.api.ActorManager;
19 | import org.junit.Test;
20 |
21 | import java.util.Collection;
22 | import java.util.List;
23 |
24 | /**
25 | * User: APOPOV
26 | * Date: 05.10.13
27 | */
28 | public class PingPongExample {
29 |
30 | @Test
31 | public void testPingPong() {
32 |
33 | ActorManager actorManager = new ActorManager();
34 |
35 | int pNumber = Runtime.getRuntime().availableProcessors();
36 |
37 | Actor1 actor1 = actorManager.createActor(new Actor1Impl(1000000, actorManager));
38 | List actor2Array = actorManager.createActors(new Actor2Impl(), pNumber);
39 |
40 | for (Actor2 actor2 : actor2Array) {
41 | actor1.startPings(actor2);
42 | }
43 |
44 | //this method call should block the current thread
45 | // and the Actor proxy should return the result when
46 | // it will be available after processing all messages passed to actor1...
47 |
48 | Integer count = actor1.getCount();
49 |
50 | // if the actor returns as a result another actor then the actor manager will return an
51 | // empty proxy of an actor
52 |
53 | System.out.println("final count = " + count);
54 | }
55 |
56 | public interface Actor1 {
57 |
58 | void startPings(Actor2 actor2);
59 |
60 | void pong(Actor2 actor2, String s);
61 |
62 | Integer getCount();
63 | }
64 |
65 | public interface Actor2 {
66 |
67 | void ping(Actor1 actor1, int count);
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/plainjava/Actor1Impl.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.plainjava;
17 |
18 |
19 | class Actor1Impl implements PlainJavaExample.Actor1 {
20 |
21 | int n;
22 | int count = 0;
23 | final long startTime;
24 |
25 |
26 | public Actor1Impl(int i) {
27 | this.n = i;
28 |
29 | startTime = System.currentTimeMillis();
30 | }
31 |
32 | public void pong(PlainJavaExample.Actor2 actor2, String s) {
33 | count++;
34 | if (count < n) {
35 | if (count % 100000 == 0)
36 | System.out.println(count + " pings from - " + s);
37 | actor2.ping(this, count);
38 | }
39 | else {
40 | long endTime = System.currentTimeMillis();
41 | System.out.println("super mega total count = " + count + ". In " + (endTime - startTime)/1000 + " seconds");
42 | }
43 | }
44 |
45 | public void startPings(PlainJavaExample.Actor2 actor2) {
46 | count++;
47 | actor2.ping(this, count);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/plainjava/Actor2Impl.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.plainjava;
17 |
18 | class Actor2Impl implements PlainJavaExample.Actor2 {
19 |
20 | public void ping(PlainJavaExample.Actor1 actor1, int count) {
21 | if (count % 100000 == 0)
22 | System.out.println(count + " pongs");
23 | actor1.pong(this, this.toString());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/api/src/test/java/com/asyncj/core/api/examples/plainjava/PlainJavaExample.java:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2013 Aliaksei Papou
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package com.asyncj.core.api.examples.plainjava;
17 |
18 | import org.junit.Test;
19 |
20 | /**
21 | * This example uses plain Java calls between actors and it will produce a stack overflow exception.
22 | * Such as actors calls each other recursively in one execution thread.
23 | * User: APOPOV
24 | * Date: 05.10.13
25 | */
26 | public class PlainJavaExample {
27 |
28 | @Test
29 | public void testPingPong() {
30 |
31 | Actor1 actor1 = new Actor1Impl(10000000);
32 |
33 | Actor2[] actor2Array = new Actor2[Runtime.getRuntime().availableProcessors()];
34 |
35 | for (int i = 0; i < actor2Array.length; i++) {
36 | actor2Array[i] = new Actor2Impl();
37 | }
38 |
39 | for (int i = 0; i < actor2Array.length; i++) {
40 | actor1.startPings(actor2Array[i]);
41 | }
42 |
43 | try {
44 | Thread.currentThread().join();
45 | } catch (InterruptedException e) {
46 | throw new RuntimeException(e);
47 | }
48 | }
49 |
50 | public interface Actor1 {
51 | void startPings(Actor2 actor2);
52 | void pong(Actor2 actor2, String s);
53 | }
54 |
55 | public interface Actor2 {
56 | void ping(Actor1 actor1, int count);
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------