рдЬрд╛рд╡рд╛ / GPars рдЖрдзрд╛рд░рд┐рдд рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХрд╛ рдкрд░рд┐рдЪрдп, рднрд╛рдЧ I

GPars рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдПрдкреАрдЖрдИ рдФрд░ рдордзреНрдпрдо рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рдПрдХ рдмрд╣реБ- рд╕реНрддрд░реАрдп рдХрд╛рд░реНрдп рдХрд╛ рд╕рдорд╛рдзрд╛рди, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо "рд░рд╛рд╖реНрдЯреНрд░реАрдп рдЕрд░реНрдерд╡реНрдпрд╡рд╕реНрдерд╛" рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред

рдпрд╣ рд▓реЗрдЦ "рдЬрд╛рд╡рд╛ рдореЗрдВ рдорд▓реНрдЯреАрдХреЛрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ" рдкрд╛рдареНрдпрдХреНрд░рдо рдХреЛ рдкрдврд╝рдиреЗ рдХреА рддреИрдпрд╛рд░реА рдореЗрдВ рдЬрд╛рд╡рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╡рд┐рднрд┐рдиреНрди рдЕрднрд┐рдиреЗрддрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рдПрдХ рдЕрдзреНрдпрдпрди рдХреЗ рджреМрд░рд╛рди рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ред

рдореИрдВ рдСрдирд▓рд╛рдЗрди рд╢рд┐рдХреНрд╖рд╛ рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо udemy.com (рдХреМрд░рд╕реЗрд░рд╛ / рдПрдбрдПрдХреНрд╕ рдХреЗ рд╕рдорд╛рди) рдкрд░ рдЬрд╛рд╡рд╛ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд╕реНрдХрд╛рд▓рд╛ рднреА рд╕рд┐рдЦрд╛рддрд╛ рд╣реВрдВред

рдпрд╣ рд▓реЗрдЦреЛрдВ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдкрд╣рд▓рд╛ рд▓реЗрдЦ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдХреБрдЫ рдореЙрдбрд▓ рд╕рдорд╕реНрдпрд╛ рдкрд░ рдЕрдиреНрдп рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдПрдкреАрдЖрдИ, рдкреНрд░рджрд░реНрд╢рди, рдФрд░ рдЕрдХреНрдХрд╛ рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдирд╛ рд╣реИред рдпрд╣ рд▓реЗрдЦ GPars рдкрд░ рдЗрд╕ рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛ рдФрд░ рд╕рдорд╛рдзрд╛рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

GPars рдПрдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИ рдЬреЛ рдХреНрд▓реЙрдЬреБрд░ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рд╕рдорд╛рдирд╛рдВрддрд░ рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╛рдкрдХ рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред
GPars рдкреЗрд╢реЗрд╡рд░реЛрдВ


"рд╕реНрдерд╛рдкрдирд╛" GPars


рдорд╛рд╡реЗрди GPars рдФрд░ Groovy рдореЗрдВ рдкреНрд▓рдЧ рдХрд░реЗрдВ
<dependency> <groupId>org.codehaus.gpars</groupId> <artifactId>gpars</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.2.2</version> </dependency> 


рдорд╛рд╡реЗрди рдХреЗ рдмрд┐рдирд╛, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдХреЗрд╡рд▓ GPars-1.1.0 ( рд╕реНрд░реЛрдд ) рдФрд░ рдЧреНрд░реВрд╡реА -реи.реи ( рд╕реНрд░реЛрдд ) рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ рдФрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред

рд╕реНрдЯреЗрдЯрд▓реЗрд╕ рдЕрднрд┐рдиреЗрддрд╛


рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
рд╣рдо рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рд╕рдВрджреЗрд╢ рднреЗрдЬ рд░рд╣реЗ рд╣реИрдВред
 import groovyx.gpars.actor.*; public class Demo { public static void main(String[] args) throws Exception { Actor actor = new DynamicDispatchActor() { public void onMessage(String msg) { System.out.println("receive: " + msg); } }.start(); actor.send("Hello!"); System.in.read(); } } >> receive: Hello! 


рд╕рдВрджреЗрд╢ рднреЗрдЬреЗрдВ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ
 import groovyx.gpars.actor.*; public class Demo { public static void main(String[] args) throws Exception { Actor actor = new DynamicDispatchActor() { public void onMessage(String msg) { System.out.println("ping: " + msg); getSender().send(msg.toUpperCase()); } }.start(); System.out.println("pong: " + actor.sendAndWait("Hello!")); } } >> ping: Hello! >> pong: HELLO! 


рд╣рдо рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЙрд▓рдмреИрдХ рдХреЛ рд▓рдЯрдХрд╛рддреЗ рд╣реИрдВ
 import groovyx.gpars.MessagingRunnable; import groovyx.gpars.actor.*; public class Demo { public static void main(String[] args) throws Exception { Actor actor = new DynamicDispatchActor() { public void onMessage(String msg) { System.out.println("ping: " + msg); getSender().send(msg.toUpperCase()); } }.start(); actor.sendAndContinue("Hello!", new MessagingRunnable<String>() { protected void doRun(String msg) { System.out.println("pong: " + msg); } }); System.in.read(); } } >> ping: Hello! >> pong: HELLO! 


рдкреНрд░рд╛рдкреНрдд рд╕рдВрджреЗрд╢ рдХреЗ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкреИрдЯрд░реНрди рдХрд╛ рдорд┐рд▓рд╛рди рдХрд░рдирд╛
 import groovyx.gpars.actor.*; public class Demo { public static void main(String[] args) throws Exception { Actor actor = new DynamicDispatchActor() { public void onMessage(String arg) { getSender().send(arg.toUpperCase()); } public void onMessage(Long arg) { getSender().send(1000 + arg); } }.start(); System.out.println("42.0 -> " + actor.sendAndWait(42.0)); } } >> Hello! -> HELLO! >> 42 -> 1042 


рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рд╕реЗ рдЙрдкрдпреБрдХреНрдд рд╣реИрдВрдбрд▓рд░ рдирд╣реАрдВ рдорд┐рд▓рд╛
 import groovyx.gpars.actor.*; public class Demo { public static void main(String[] args) throws Exception { Actor actor = new DynamicDispatchActor() { public void onMessage(String arg) { getSender().send(arg.toUpperCase()); } public void onMessage(Long arg) { getSender().send(1000 + arg); } }.start(); System.out.println("42.0 -> " + actor.sendAndWait(42.0)); } } >> An exception occurred in the Actor thread Actor Thread 1 >> groovy.lang.MissingMethodException: No signature of method: >> net.golovach.Demo_4$1.onMessage() is applicable for argument types: (java.lang.Double) values: [42.0] >> Possible solutions: onMessage(java.lang.Long), onMessage(java.lang.String) >> at org.codehaus.groovy.runtime.ScriptBytecodeAdapter ... >> ... 


рдЬреЛ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ
- "рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди" рдСрдирдореИрд╕реЗрдЬ рдХреЗ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдЕрддрд┐рднрд╛рд░рд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЪрдпрди рдХрд░рддрд╛ рд╣реИ (<рдПрдХ- arg>) рд╡рд┐рдзрд┐, рдЕрдЧрд░ рдХреЛрдИ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдПрдХ рдЕрдкрд╡рд╛рдж рдорд┐рд▓рддрд╛ рд╣реИ
- рдЕрднрд┐рдиреЗрддрд╛ "рдбреЗрдореЙрди" рдереНрд░реЗрдбреНрд╕ рдХреЗ рдПрдХ рдкреВрд▓ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рдЬреЗрд╡реАрдПрдо рдХреЛ рд╕рдордп рд╕реЗ рдкрд╣рд▓реЗ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЦреНрдп () рд╡рд┐рдзрд┐ (рдореИрдВрдиреЗ System.in.read () рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛) рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рд╕реНрдердЧрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
- рдЙрддреНрддрд░ () рд╡рд┐рдзрд┐ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЬрдм рдбрд╛рдпрдиреЗрдорд┐рдХрдбрд┐рд╕реНрдкреИрдХреНрдЯрд░ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИ, рддреЛ рдмрд╣реБрдд рд╕рд╛рд░реА рд╡рд┐рдзрд┐рдпрд╛рдВ рдЕрднрд┐рдиреЗрддрд╛ рдХреЗ "рдиреЗрдорд╕реНрдкреЗрд╕" рдореЗрдВ рдЖрддреА рд╣реИрдВ (рдЙрддреНрддрд░, replIfExists, getSender, рд╕рдорд╛рдкреНрдд, ...

рд╣рд╛рд▓рд╛рдБрдХрд┐ GPars рдХреЗ рд▓реЗрдЦрдХ рдбрд╛рдпрдирд╛рдореЗрдбрд╕реНрдкрд╛рдЗрдЪреИрдХреНрдЯрд░рдПрдХреНрдЯрд░ рд╕реНрдЯреЗрдЯ рд╕реНрдЯреЗрдЯрд▓реЗрд╕ рдПрдХреНрдЯрд░ рдХреЗ рд╡рд╛рд░рд┐рд╕ рдХрд╣рд▓рд╛рддреЗ рд╣реИрдВ, рдпреЗ рдЬрд╛рд╡рд╛ рдХреНрд▓рд╛рд╕реЗрд╕ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ рдЬреЛ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддреА рдХреНрд╖реЗрддреНрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдореЗрдВ рдЕрдкрдирд╛ рд░рд╛рдЬреНрдп рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░реЗрдВ
 import groovyx.gpars.actor.*; import java.util.ArrayList; import java.util.List; public class StatelessActorTest { public static void main(String[] args) throws InterruptedException { Actor actor = new DynamicDispatchActor() { private final List<Double> state = new ArrayList<>(); public void onMessage(final Double msg) { state.add(msg); reply(state); } }.start(); System.out.println("answer: " + actor.sendAndWait(1.0)); System.out.println("answer: " + actor.sendAndWait(2.0)); System.out.println("answer: " + actor.sendAndWait(3.0)); System.out.println("answer: " + actor.sendAndWait(4.0)); System.out.println("answer: " + actor.sendAndWait(5.0)); } } >> answer: [1.0] >> answer: [1.0, 2.0] >> answer: [1.0, 2.0, 3.0] >> answer: [1.0, 2.0, 3.0, 4.0] >> answer: [1.0, 2.0, 3.0, 4.0, 5.0] 


рд╕реНрдЯреЗрдЯрдлреБрд▓ рдПрдХреНрдЯрд░


рд╡рд┐рднрд╛рдЬрди рдХреЛ рд╕реНрдЯреЗрдЯрд▓реЗрд╕ / рд╕реНрдЯреЗрдЯрдлреБрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реБрдП, рд▓реЗрдЦрдХреЛрдВ рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╕реНрдЯреЗрдЯрдлреБрд▓ рдПрдХреНрдЯрд░ рдЖрдкрдХреЛ рд╕реНрдЯреЗрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд░реВрдк рд╕реЗ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЖрдЗрдП рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ (рдбрд┐рдлрд╛рд▓реНрдЯрд░ рдХреЗ рд╡рдВрд╢рдЬ - рд╕реНрдЯреЗрдЯрдлреБрд▓ рдПрдХреНрдЯрд░)
 import groovyx.gpars.MessagingRunnable; import groovyx.gpars.actor.*; import static java.util.Arrays.asList; public class StatefulActorTest { public static void main(String[] args) throws Exception { Actor actor = new MyStatefulActor().start(); actor.send("A"); actor.send(1.0); actor.send(Arrays.asList(1, 2, 3)); actor.send("B"); actor.send(2.0); actor.send(Arrays.asList(4, 5, 6)); System.in.read(); } private static class MyStatefulActor extends DefaultActor { protected void act() { loop(new Runnable() { public void run() { react(new MessagingRunnable<Object>(this) { protected void doRun(final Object msg) { System.out.println("react: " + msg); } }); } }); } } } >> react: A >> react: 1.0 >> react: [1, 2, 3] >> react: B >> react: 2.0 >> react: [4, 5, 6] 


рд╣рд╛рд▓рд╛рдБрдХрд┐, рд░рд╛рдЬреНрдп рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХреНрд░рд┐рдпрд╛рдиреНрд╡рдпрди рдмрд┐рд▓реНрдХреБрд▓ рднреА рдмрджрдмреВрджрд╛рд░ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЪрд▓рддреЗ рд╣реИрдВ (Java рдРрд╕реА рдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рднрд╛рд╖рд╛ рдирд╣реАрдВ рд╣реИ, Clojure / Scala рдкрд░ рдпрд╣ рдХреЛрдб рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХреЙрдореНрдкреИрдХреНрдЯ рджрд┐рдЦрддрд╛ рд╣реИ)
 import groovyx.gpars.MessagingRunnable; import groovyx.gpars.actor.*; import java.util.List; import static java.util.Arrays.asList; public class StatefulActorTest { public static void main(String[] args) throws Exception { Actor actor = new MyStatefulActor().start(); actor.send("A"); actor.send(1.0); actor.send(asList(1, 2, 3)); actor.send("B"); actor.send(2.0); actor.send(asList(4, 5, 6)); System.in.read(); } private static class MyStatefulActor extends DefaultActor { protected void act() { loop(new Runnable() { public void run() { react(new MessagingRunnable<String>(this) { protected void doRun(final String msg) { System.out.println("Stage #0: " + msg); react(new MessagingRunnable<Double>() { protected void doRun(final Double msg) { System.out.println(" Stage #1: " + msg); react(new MessagingRunnable<List<Integer>>() { protected void doRun(final List<Integer> msg) { System.out.println(" Stage #2: " + msg + "\n"); } }); } }); } }); } }); } } } >> Stage #0: A >> Stage #1: 1.0 >> Stage #2: [1, 2, 3] >> >> Stage #0: B >> Stage #1: 2.0 >> Stage #2: [4, 5, 6] 


рдЦреИрд░, рдпрд╛ рдЪрд▓реЛ рдЕрдирд╛рдо рд╡рд░реНрдЧреЛрдВ рдХреЗ рдЗрд╕ рднрдпрд╛рдирдХ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдПрдВ рдФрд░ "рд░рд╛рдЬреНрдп рдХреЛ рднреМрддрд┐рдХ рдмрдирд╛рдПрдВ"
 import groovyx.gpars.MessagingRunnable; import groovyx.gpars.actor.*; import java.util.List; import static java.util.Arrays.asList; public class StatefulActorTest { public static void main(String[] args) throws Exception { Actor actor = new MyStatefulActor().start(); actor.send("A"); actor.send(1.0); actor.send(asList(1, 2, 3)); actor.send("B"); actor.send(2.0); actor.send(asList(4, 5, 6)); System.in.read(); } private static class MyStatefulActor extends DefaultActor { protected void act() { loop(new Runnable() { public void run() { react(new Stage0(MyStatefulActor.this)); } }); } } private static class Stage0 extends MessagingRunnable<String> { private final DefaultActor owner; private Stage0(DefaultActor owner) {this.owner = owner;} protected void doRun(final String msg) { System.out.println("Stage #0: " + msg); owner.react(new Stage1(owner)); } } private static class Stage1 extends MessagingRunnable<Double> { private final DefaultActor owner; private Stage1(DefaultActor owner) {this.owner = owner;} protected void doRun(final Double msg) { System.out.println(" Stage #1: " + msg); owner.react(new Stage2()); } } private static class Stage2 extends MessagingRunnable<List<Integer>> { protected void doRun(final List<Integer> msg) { System.out.println(" Stage #2: " + msg + "\n"); } } } 

рд╣рд╛рдВ, рд╣рд╛рдВ, рдореИрдВ рдЖрдкрд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕рд╣рдордд рд╣реВрдВ, рдЬрд╛рд╡рд╛ рдПрдХ рдЕрддреНрдпрдВрдд рдХреНрд░рд┐рдпрд╛рддреНрдордХ рднрд╛рд╖рд╛ рд╣реИред

рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рд╕рдВрдХреНрд░рдордг рдЖрд░реЗрдЦ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ (рд╣рдордиреЗ рддрд░реНрдХ рдХреЛ рдХрд╛рдВрдЯрд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛)
 // START // ----- // | // | // | // | +--------+ // +->| Stage0 | ---String----+ // +--------+ | // ^ v // | +--------+ // | | Stage1 | // List<Integer> +--------+ // | | // | +--------+ Double // +--| Stage2 |<-------+ // +--------+ 


рдШрдбрд╝реА


рдореЗрд░реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдПрдХ рдЯрд╛рдЗрдорд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА - рдХреБрдЫ рдРрд╕рд╛ рдЬреЛ рдореБрдЭреЗ рдирд┐рд╢реНрдЪрд┐рдд рдЕрд╡рдзрд┐ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реВрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред "рдирд┐рдпрдорд┐рдд" рдЬрд╛рд╡рд╛ рдореЗрдВ, рд╣рдо java.util.concurrent.ScheduledThreadPoolExecutor рдпрд╛ java.util.Timer рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рдмрд╕реЗ рдХрдо рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╣рдо рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рд╣реИрдВ!
рдпрд╣ рдПрдХ рд╕реНрдЯреЗрдЯрдлреБрд▓ рдПрдХреНрдЯрд░ рд╣реИ рдЬреЛ рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ () рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рд╕рдВрджреЗрд╢ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред рдпрджрд┐ рдЗрд╕ рдЕрд╡рдзрд┐ рдХреЗ рджреМрд░рд╛рди рдХреЛрдИ рд╕рдВрджреЗрд╢ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ, рддреЛ GPars рдЕрд╡рд╕рдВрд░рдЪрдирд╛ рд╣рдореЗрдВ рдПрдХ рдЕрднрд┐рдиреЗрддрд╛ рднреЗрдЬрддреА рд╣реИред рд╕рдВрджреЗрд╢ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВред (рдпрд╣ рд╕рд┐рд░реНрдл "рдЯрд╛рдЗрдордЯрд╛рдЗрдо" рд▓рд╛рдЗрди рд╣реИ) рдФрд░ рд╣рдо рдЕрдкрдиреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЛ рдордзреНрдпрд╛рдВрддрд░ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рд╕реЗ рд╕рдВрджреЗрд╢ "рд╡рд╛рдкрд╕" рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЯрд╛рдЗрдорд░ рдХреЛ "рдмрдВрдж" рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ - рддреЛ рдЙрд╕реЗ рдХреЛрдИ рдЕрдиреНрдп рд╕рдВрджреЗрд╢ рднреЗрдЬреЗрдВ (рдореИрдВ рдЙрд╕реЗ "KILL" рд╕реНрдЯреНрд░рд┐рдВрдЧ рднреЗрдЬреВрдВрдЧрд╛)
 import groovyx.gpars.MessagingRunnable; import groovyx.gpars.actor.*; import groovyx.gpars.actor.impl.MessageStream; import static java.util.concurrent.TimeUnit.MILLISECONDS; public class Timer<T> extends DefaultActor { private final long timeout; private final T timeoutMsg; private final MessageStream replyTo; public Timer(long timeout, T timeoutMsg, MessageStream replyTo) { this.timeout = timeout; this.timeoutMsg = timeoutMsg; this.replyTo = replyTo; } protected void act() { loop(new Runnable() { public void run() { react(timeout, MILLISECONDS, new MessagingRunnable() { protected void doRun(Object argument) { if (Actor.TIMEOUT.equals(argument)) { replyTo.send(timeoutMsg); } terminate(); } }); } }); } } 


рдЯрд╛рдЗрдорд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдгред
рдореИрдВ рджреЛ рдЯрд╛рдЗрдорд░ рдЯрд╛рдЗрдорд░ рдФрд░ рдЯрд╛рдЗрдорд░ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВ, рдЬреЛ 1000 рдореА рдХреА рджреЗрд░реА рдХреЗ рд╕рд╛рде рдореБрдЭреЗ рдХреНрд░рдорд╢рдГ "рдПрдХреНрд╕" рдФрд░ "рд╡рд╛рдИ" рд╕рдВрджреЗрд╢ рднреЗрдЬреЗрдЧрд╛ред рд▓реЗрдХрд┐рди 500 рдореА рдХреЗ рдмрд╛рдж рдореИрдВрдиреЗ рдЕрдкрдирд╛ рджрд┐рдорд╛рдЧ рдмрджрд▓ рджрд┐рдпрд╛ рдФрд░ "рдиреЗрдХреНрдб" рдЯрд╛рдЗрдорд░рдПрдХреНрд╕ред
 import groovyx.gpars.actor.Actor; import groovyx.gpars.actor.impl.MessageStream; public class TimerDemo { public static void main(String[] args) throws Exception { Actor timerX = new Timer<>(1000, "X", new MessageStream() { public MessageStream send(Object msg) { System.out.println("timerX send timeout message: '" + msg + "'"); return this; } }).start(); Actor timerY = new Timer<>(1000, "Y", new MessageStream() { public MessageStream send(Object msg) { System.out.println("timerY send timeout message: '" + msg + "'"); return this; } }).start(); Thread.sleep(500); timerX.send("KILL"); System.in.read(); } } >> timerY send timeout message: 'Y' 


рд╕рдорд╕реНрдпрд╛ рдмрдпрд╛рди рдФрд░ рд╕рдорд╛рдзрд╛рди рдпреЛрдЬрдирд╛


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмрд╣реБрдд рд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╕реНрдпрд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
1. рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдИ рд╕реВрддреНрд░ рд╣реИрдВ рдЬреЛ рдЕрдХреНрд╕рд░ рдХрд┐рд╕реА рди рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░рдг рдмрдирддреЗ рд╣реИрдВред
2. рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рджреЛ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ: рдХрд┐рд╕реА рдПрдХрд▓ рддрд░реНрдХ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдФрд░ рддрд░реНрдХреЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ред
3. рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдРрд╕рд╛ рд╣реИ рдХрд┐ рдПрдХ рддрд░реНрдХ рд╕реВрдЪреА рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдкреНрд░рддреНрдпреЗрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдпреЛрдЧ рд╕реЗ рдХрдо рд╕рд┐рд╕реНрдЯрдо рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЦрдкрдд рдХрд░рддрд╛ рд╣реИред
4. рдХрд╛рд░реНрдп рдкреНрд░рд╡рд╛рд╣ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдмреАрдЪ рдХреБрдЫ рдмреИрдЪрд░ рд▓рдЧрд╛рдиреЗ рдХрд╛ рд╣реИ, рдЬреЛ рдкреНрд░рд╡рд╛рд╣ рд╕реЗ рддрд░реНрдХреЛрдВ рдХреЛ рдПрдХ "рдмрдВрдбрд▓" рдореЗрдВ рдПрдХрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рднреЗрдЬрддрд╛ рд╣реИ, рдпрд╣ рд╕реВрдЪреА рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдмреИрдЪрд░ "рдкреНрд░реЗрд╖рд┐рдд" рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкреНрд░реЗрд╖рдХ рдХреЛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
5. рдмреИрдЪрд░ рджреЛ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ: рдЙрдиреНрд╣реЛрдВрдиреЗ рдкрд░реНрдпрд╛рдкреНрдд рдЖрдХрд╛рд░ рдХрд╛ рдПрдХ "рдмрдВрдбрд▓" рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдпрд╛ рдПрдХ рд╕рдордп-рдЖрдЙрдЯ рдЕрд╡рдзрд┐ рдХреЗ рджреМрд░рд╛рди рдЬрд┐рд╕рдХреЗ рджреМрд░рд╛рди рдПрдХ рдкреВрд░рд╛ "рдмрдВрдбрд▓" рдПрдХрддреНрд░ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рдерд╛, рд▓реЗрдХрд┐рди рдереНрд░реЗрдбреНрд╕ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред

рдЖрдЗрдП рдПрдХ рд╕рдорд╛рдзрд╛рди рдпреЛрдЬрдирд╛ рджреЗрдЦреЗрдВред
рдЯрд╛рдЗрдордЖрдЙрдЯ 100ms, "рдмрдВрдбрд▓" рдХрд╛ рдЕрдзрд┐рдХрддрдо рдЖрдХрд╛рд░ - 3 рддрд░реНрдХ

рд╕рдордп 0 рдкрд░, рдкреНрд░рд╡рд╛рд╣ T-0 рддрд░реНрдХ "A" рднреЗрдЬрддрд╛ рд╣реИред рдмреИрдЪрд░ "рд╕рд╛рдл" рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИ, рдкреАрдврд╝реА 0
 //time:0 // // T-0 --"A"-----> +-------+ generationId=0 // T-1 |Batcher| argList=[] // T-2 +-------+ replyToList=[] 


рдПрдХ рдкрд▓ рдХреЗ рдмрд╛рдж, рдмреИрдЪрд░ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ "рдП" рдХреЛ рдЫреЛрдЯрд╛ рдХрд░рдирд╛ рдФрд░ рдЯреА-0 рдкрд░ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЯрд╛рдЗрдорд░ рдкреАрдврд╝реА 0 рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рдХрд┐рдпрд╛
 // +-----+ timeoutMsg=0 // |Timer| timeout=100 //time:0.001 +-----+ // // T-0 +-------+ generationId=0 // T-1 |Batcher| argList=["A"] // T-2 +-------+ replyToList=[T-0] 


25 рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреЗ рд╕рдордп, рдЯреА -1 рд╕реНрдЯреНрд░реАрдо рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП "рдмреА" рднреЗрдЬрддрд╛ рд╣реИ
 // +-----+ timeoutMsg=0 // |Timer| timeout=100 //time:25 +-----+ // // T-0 +-------+ generationId=0 // T-1 ---"B"----> |Batcher| argList=["A"] // T-2 +-------+ replyToList=[T-0] 


рдПрдХ рдкрд▓ рдХреЗ рдмрд╛рдж, рдмреИрдЪрд░ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ "рдП" рдФрд░ "рдмреА" рдХреЛ рдЫреЛрдЯрд╛ рдХрд░рдирд╛ рдФрд░ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдЯреА-0 рдФрд░ рдЯреА -1 рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ
 // +-----+ timeoutMsg=0 // |Timer| timeout=100 //time:25.001 +-----+ // // T-0 +-------+ generationId=0 // T-1 |Batcher| argList=["A","B"] // T-2 +-------+ replyToList=[T-0,T-1] 


50 рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреЗ рд╕рдордп рдореЗрдВ, рдЯреА -2 рд╕реНрдЯреНрд░реАрдо рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП "рд╕реА" рднреЗрдЬрддрд╛ рд╣реИ
 // +-----+ timeoutMsg=0 // |Timer| timeout=100 //time:50 +-----+ // // T-0 +-------+ generationId=0 // T-1 |Batcher| argList=["A","B"] // T-2 ----"C"---> +-------+ replyToList=[T-0,T-1] 


рдПрдХ рдкрд▓ рдХреЗ рдмрд╛рдж, рдмреИрдЪрд░ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ "рдП", "рдмреА" рдФрд░ "рд╕реА" рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдФрд░ рдЗрд╕реЗ рдкреНрд░рд╡рд╛рд╣ рдЯреА -0, рдЯреА -1 рдФрд░ рдЯреА -2 рдореЗрдВ рд▓реМрдЯрд╛ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ "рдмрдВрдбрд▓" рднрд░рд╛ рд╣реБрдЖ рд╣реИ рдФрд░ рдЯрд╛рдЗрдорд░ "рдорд╛рд░рддрд╛ рд╣реИ"
 // +-----+ timeoutMsg=0 // +-"KILL"->|Timer| timeout=100 //time:50.001 | +-----+ // | // T-0 +-------+ generationId=0 // T-1 |Batcher| argList=["A","B","C"] // T-2 +-------+ replyToList=[T-0,T-1,T-2] 


рдПрдХ рдкрд▓ рдХреЗ рдмрд╛рдж, рдмреИрдЪрд░ рдПрдХ рдЕрд▓рдЧ рдЕрднрд┐рдиреЗрддрд╛ (рдПрдиреЛрдирд┐рдорд╕) рдХреЛ рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рджреЗрддрд╛ рд╣реИ, рд░рд╛рдЬреНрдп рдХреЛ рд╕рд╛рдл рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкреАрдврд╝реА рдХреЛ 0 рд╕реЗ 1 рддрдХ рдмрджрд▓рддрд╛ рд╣реИ
 //time:50.002 // // T-0 +-------+ generationId=1 // T-1 |Batcher| argList=[] // T-2 +-------+ replyToList=[] // // +---------+ argList=["A","B","C"] // |anonymous| replyToList=[T-0,T-1,T-2] // +---------+ 


рдПрдХ рдкрд▓ рдХреЗ рдмрд╛рдж ("рд╕реНрдЯреЛрд░реАрдмреЛрд░реНрдб" рдХреЗ рд▓рд┐рдП рдореИрдВ рдорд╛рди рд▓реВрдВрдЧрд╛ рдХрд┐ рдЧрдгрдирд╛рдПрдБ рддрд╛рддреНрдХрд╛рд▓рд┐рдХ рд╣реИрдВ) рдПрдХ рдЕрдирд╛рдо рдЕрднрд┐рдиреЗрддрд╛ рддрд░реНрдХреЛрдВ рдХреА рд╕реВрдЪреА рдкрд░ рдПрдХ рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИ ["A", "B", "C"] -> ["res # A", "res # B", " Res # C "]
 //time:50.003 // // T-0 +-------+ generationId=1 // T-1 |Batcher| argList=[] // T-2 +-------+ replyToList=[] // // +---------+ resultList=["res#A","res#B","res#B"] // |anonymous| replyToList=[T-0,T-1,T-2] // +---------+ 


рдПрдХ рдкрд▓ рдХреЗ рдмрд╛рдж, рдПрдХ рдЕрдирд╛рдо рдЕрднрд┐рдиреЗрддрд╛ рдереНрд░реЗрдбреНрд╕ рдХреЗ рд▓рд┐рдП рдЧрдгрдирд╛ рдкрд░рд┐рдгрд╛рдо рд╡рд┐рддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ
 //time:50.004 // // T-0 <-----------+ +-------+ generationId=1 // T-1 <---------+ | |Batcher| argList=[] // T-2 <-------+ | | +-------+ replyToList=[] // | | | // | | +---"res#A"--- +---------+ // | +---"res#B"----- |anonymous| // +--"res#C"-------- +---------+ 


рдПрдХ рдкрд▓ рдХреЗ рдмрд╛рдж, рд╕рд┐рд╕реНрдЯрдо рдЕрдкрдиреА рдореВрд▓ "рд╢реБрджреНрдз" рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддрд╛ рд╣реИ
 //time:50.005 // // T-0 +-------+ generationId=1 // T-1 |Batcher| argList=[] // T-2 +-------+ replyToList=[] 


рдмрд╛рдж рдореЗрдВ, рд╕рдордп 75 рдкрд░, рдЯреА -2 рд╕реНрдЯреНрд░реАрдо "рдбреА" рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдЧреБрдЬрд░рддрд╛ рд╣реИ
 //time:75 // // T-0 +-------+ generationId=1 // T-1 |Batcher| argList=[] // T-2 ----"D"---> +-------+ replyToList=[] 


рдПрдХ рдкрд▓ рдХреЗ рдмрд╛рдж, рдмреИрдЪрд░ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ "рдбреА" рдХреЛ рдЫреЛрдЯрд╛ рдХрд░рдирд╛ рдФрд░ рдЯреА -2 рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреАрдврд╝реА рдХреЗ рд▓рд┐рдП рдПрдХ рдЯрд╛рдЗрдорд░ 1
 // +-----+ timeoutMsg=1 // |Timer| timeout=100 //time:75.001 +-----+ // // T-0 +-------+ generationId=1 // T-1 |Batcher| argList=["D"] // T-2 +-------+ replyToList=[T-2] 


100ms (175ms рдкрд░) рдХреЗ рдмрд╛рдж, GPars рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪрд╛ рдкреНрд░рддреАрдХреНрд╖рд╛ рдЕрд╡рдзрд┐ рдХреА рд╕рдорд╛рдкреНрддрд┐ рдХреЗ рдЯрд╛рдЗрдорд░ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ
 // +--"TIMEOUT"-- // | // v // +-----+ timeoutMsg=1 // |Timer| timeout=100 //time:175 +-----+ // // T-0 +-------+ generationId=1 // T-1 |Batcher| argList=["D"] // T-2 +-------+ replyToList=[T-2] 


рдПрдХ рдХреНрд╖рдг рдмрд╛рдж, рдЯрд╛рдЗрдорд░ рдмреИрдЪрд░ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдкреАрдврд╝реА 1 рдХрд╛ рд╕рдордп рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ рд╕рдорд╛рдкреНрдд () рдХреЙрд▓ рдХрд░рдХреЗ рдЖрддреНрдорд╣рддреНрдпрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ
 // +-----+ timeoutMsg=1 // +----1-----|Timer| timeout=100 //time:175.001 | +-----+ // v // T-0 +-------+ generationId=1 // T-1 |Batcher| argList=["D"] // T-2 +-------+ replyToList=[T-2] 


рдПрдХ рдЕрдирд╛рдо рдЕрднрд┐рдиреЗрддрд╛ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рддрд░реНрдХ рд╕реВрдЪреА рдкрд░ рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ (рдЬрд┐рд╕рдореЗрдВ рдХреЗрд╡рд▓ 1 рддрд░реНрдХ рд╣реИ)ред рдЬрдирд░реЗрд╢рди 1 2 рдореЗрдВ рдмрджрд▓рддрд╛ рд╣реИ
 //time:175.002 // // T-0 +-------+ generationId=2 // T-1 |Batcher| argList=[] // T-2 +-------+ replyToList=[] // // +---------+ argList=["D"] // |anonymous| replyToList=[T-2] // +---------+ 


рдЕрднрд┐рдиреЗрддрд╛ рдиреЗ рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ
 //time:175.003 // // T-0 +-------+ generationId=2 // T-1 |Batcher| argList=[] // T-2 +-------+ replyToList=[] // // +---------+ resultList=["res#D"] // |anonymous| replyToList=[T-2] // +---------+ 


рдЕрднрд┐рдиреЗрддрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИ
 //time:175.004 // // T-0 +-------+generationId=2 // T-1 |Batcher|argList=[] // T-2 <-------+ +-------+replyToList=[] // | // | +---------+ // +--"res#C"----- |anonymous| // +---------+ 


рдЕрдкрдиреА рдореВрд▓ "рд╢реБрджреНрдз" рдЕрд╡рд╕реНрдерд╛ рдореЗрдВ рдкреНрд░рдгрд╛рд▓реА
 //time:175.005 // // T-0 +-------+ generationId=2 // T-1 |Batcher| argList=[] // T-2 +-------+ replyToList=[] 


рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдХрд░рдирд╛



рдмреИрдЪрдкреНрд░реЛрд╕реЗрд╕рд░ - "рдлрд╝рдВрдХреНрд╢рди" рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ред "рдмреИрдЪ рдореЛрдб" рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг
 import java.util.List; public interface BatchProcessor<ARG, RES> { List<RES> onBatch(List<ARG> argList) throws Exception; } 


рдмреИрдЪ - рдПрдХ рд╡рд░реНрдЧ рдЬреЛ "рдкреИрдХ" рддрд░реНрдХ рджреЗрддрд╛ рд╣реИред рдХреЛрд░ рд╕рдорд╛рдзрд╛рди
 import groovyx.gpars.actor.*; import groovyx.gpars.actor.impl.MessageStream; import java.util.*; public class Batcher<ARG, RES> extends DynamicDispatchActor { // fixed parameters private final BatchProcessor<ARG, RES> processor; private final int maxBatchSize; private final long batchWaitTimeout; // current state private final List<ARG> argList = new ArrayList<>(); private final List<MessageStream> replyToList = new ArrayList<>(); private long generationId = 0; private Actor lastTimer; public Batcher(BatchProcessor<ARG, RES> processor, int maxBatchSize, long batchWaitTimeout) { this.processor = processor; this.maxBatchSize = maxBatchSize; this.batchWaitTimeout = batchWaitTimeout; } public void onMessage(final ARG elem) { argList.add(elem); replyToList.add(getSender()); if (argList.size() == 1) { lastTimer = new Timer<>(batchWaitTimeout, ++generationId, this).start(); } else if (argList.size() == maxBatchSize) { lastTimer.send("KILL"); lastTimer = null; nextGeneration(); } } public void onMessage(final long timeOutId) { if (generationId == timeOutId) {nextGeneration();} } private void nextGeneration() { new DynamicDispatchActor() { public void onMessage(final Work<ARG, RES> work) throws Exception { List<RES> resultList = work.batcher.onBatch(work.argList); for (int k = 0; k < resultList.size(); k++) { work.replyToList.get(k).send(resultList.get(k)); } terminate(); } }.start().send(new Work<>(processor, new ArrayList<>(argList), new ArrayList<>(replyToList))); argList.clear(); replyToList.clear(); generationId = generationId + 1; } private static class Work<ARG, RES> { public final BatchProcessor<ARG, RES> batcher; public final List<ARG> argList; public final List<MessageStream> replyToList; public Work(BatchProcessor<ARG, RES> batcher, List<ARG> argList, List<MessageStream> replyToList) { this.batcher = batcher; this.argList = argList; this.replyToList = replyToList; } } } 


BatcherDemo рдмреИрдЪрд░ рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдкреНрд░рджрд░реНрд╢рди рд╣реИред рдпреЛрдЬрдирд╛рдмрджреНрдз рдХреЗ рд░реВрдк рдореЗрдВ рднреА
 import groovyx.gpars.actor.Actor; import java.io.IOException; import java.util.*; import java.util.concurrent.*; import static java.util.concurrent.Executors.newCachedThreadPool; public class BatcherDemo { public static final int BATCH_SIZE = 3; public static final long BATCH_TIMEOUT = 100; public static void main(String[] args) throws InterruptedException, IOException { final Actor actor = new Batcher<>(new BatchProcessor<String, String>() { public List<String> onBatch(List<String> argList) { System.out.println("onBatch(" + argList + ")"); ArrayList<String> result = new ArrayList<>(argList.size()); for (String arg : argList) { result.add("res#" + arg); } return result; } }, BATCH_SIZE, BATCH_TIMEOUT).start(); ExecutorService exec = newCachedThreadPool(); exec.submit(new Callable<Void>() { // T-0 public Void call() throws Exception { System.out.println(actor.sendAndWait(("A"))); return null; } }); exec.submit(new Callable<Void>() { // T-1 public Void call() throws Exception { Thread.sleep(25); System.out.println(actor.sendAndWait(("B"))); return null; } }); exec.submit(new Callable<Void>() { // T-2 public Void call() throws Exception { Thread.sleep(50); System.out.println(actor.sendAndWait(("C"))); Thread.sleep(25); System.out.println(actor.sendAndWait(("D"))); return null; } }); exec.shutdown(); } } >> onBatch([A, B, C]) >> res#A >> res#B >> res#C >> onBatch([D]) >> res#D 


рдирд┐рд╖реНрдХрд░реНрд╖


рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдЕрднрд┐рдиреЗрддрд╛ рдорд▓реНрдЯреА-рдереНрд░реЗрдбреЗрдб рдкреНрд░рд┐рдорд┐рдЯрд┐рд╡ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫреЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рдЬрдЯрд┐рд▓ рд╕рдВрдХреНрд░рдордг рдЖрд░реЗрдЦ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдорд┐рдд рд░рд╛рдЬреНрдп рдорд╢реАрдиреЗрдВ рд╣реИрдВ, рдЬреЛ рдЕрдиреНрдп рдмрд╛рддреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдиреЗ рд╡рд╛рд▓реА рддрд░реНрдХреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред

рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдСрдирд▓рд╛рдЗрди рдкрд╛рдП рдЧрдП рдХреЛрдб рдХреЗ рд░реВрдкрд╛рдВрддрд░ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ gpars.org/guide рд╢рд╛рдорд┐рд▓ рд╣реИрдВ ред

рджреВрд╕рд░реЗ рднрд╛рдЧ рдореЗрдВ рд╣рдо


рдпреБрдкреАрдбреА
рд░реЛрд╖ рдЯрд┐рдкреНрдкрдгреА рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж:
GPars рдХреЛ Java + Groovy рдорд┐рд╢реНрд░рдг рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╕реНрд░реЛрдд рдХреЛрдб рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдЧреНрд░реВрд╡реА рдкреИрдХреЗрдЬ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ
- groovyx.gpars.cspред *
- groovyx.gpars.paред *
- groovyx.gparsред * (рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ)

рд╕рдВрдкрд░реНрдХ рд╡рд┐рд╡рд░рдг



рдореИрдВ рдЬрд╛рд╡рд╛ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдСрдирд▓рд╛рдЗрди рдХрд░рддрд╛ рд╣реВрдВ (рдпрд╣рд╛рдВ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдкрд╛рдареНрдпрдХреНрд░рдо рд╣реИрдВ ) рдФрд░ рдЬрд╛рд╡рд╛ рдХреЛрд░ рдХреЛрд░реНрд╕ рдХреЗ рд░реАрдбрд┐рдЬрд╛рдЗрди рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рд╕рд╛рдордЧреНрд░реА рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рддрд╛ рд╣реВрдВред рдЖрдк YouTube рдЪреИрдирд▓ рдкрд░ рджрд░реНрд╢рдХреЛрдВ рдХреЗ рд╡реНрдпрд╛рдЦреНрдпрд╛рди рдХреА рд╡реАрдбрд┐рдпреЛ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╢рд╛рдпрдж рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЪреИрдирд▓ рдХрд╛ рд╡реАрдбрд┐рдпреЛ рдмреЗрд╣рддрд░ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд╣реИред

рд╕реНрдХрд╛рдЗрдк: рдЧреЛрд▓реЛрд╡рдЪрдХреНрд░реНрд╕
рдИрдореЗрд▓: GolovachCourses@gmail.com

Source: https://habr.com/ru/post/In217899/


All Articles