├── .idea ├── compiler.xml ├── deployment.xml ├── dictionaries │ └── Administrator.xml ├── encodings.xml ├── libraries │ ├── Maven__com_lmax_disruptor_3_3_6.xml │ ├── Maven__commons_logging_commons_logging_1_2.xml │ ├── Maven__junit_junit_4_12.xml │ ├── Maven__org_hamcrest_hamcrest_core_1_3.xml │ ├── Maven__org_springframework_spring_aop_4_3_4_RELEASE.xml │ ├── Maven__org_springframework_spring_beans_4_3_4_RELEASE.xml │ ├── Maven__org_springframework_spring_context_4_3_4_RELEASE.xml │ ├── Maven__org_springframework_spring_core_4_3_4_RELEASE.xml │ ├── Maven__org_springframework_spring_expression_4_3_4_RELEASE.xml │ └── Maven__org_springframework_spring_test_4_3_4_RELEASE.xml ├── misc.xml ├── modules.xml ├── sonarlint │ └── issuestore │ │ ├── 2 │ │ └── 7 │ │ │ ├── 275d783e298228506068436512433d343feb52aa │ │ │ └── 27caae5bf5995d571678d8a6b02dd32944f1a381 │ │ ├── 4 │ │ └── 4 │ │ │ └── 442292b8a7efeabbe4cc176709b833b1792140ec │ │ ├── a │ │ └── e │ │ │ └── ae5ae063b88e2ce710224b018b0fc1385937f197 │ │ ├── c │ │ ├── 2 │ │ │ └── c23081e01bee7bfef4b275a5d060400d657ba799 │ │ └── 3 │ │ │ └── c3fa69b85c67832f479c1aca58c38060292eebc9 │ │ ├── e │ │ ├── 0 │ │ │ └── e0d9f2fecabce341866e2d43813b1df05e205e4d │ │ ├── a │ │ │ └── ea0b9640f1eedf4c76609935aaa8f275336d991c │ │ └── d │ │ │ └── edf79a3801a6b29893cee48af21dd00c0c6839e4 │ │ ├── f │ │ └── 0 │ │ │ └── f016d68f06c962d3bd22c4bfc61ed5f3991514b9 │ │ └── index.pb ├── uiDesigner.xml └── workspace.xml ├── disruptor-demo.iml ├── disruptor-demo.ipr ├── disruptor-demo.iws ├── pom.xml ├── readme.md └── src ├── main ├── java │ └── com │ │ └── disruptor │ │ ├── exam │ │ ├── MemoryCache.java │ │ ├── Performer.java │ │ ├── Processor.java │ │ ├── ProcessorContext.java │ │ ├── ProcessorGroup.java │ │ ├── ProcessorGroupPool.java │ │ ├── Progressor.java │ │ ├── ScoreEvent.java │ │ ├── ScoreEventFactory.java │ │ ├── ScoreEventHandler.java │ │ ├── ScoreEventTranslator.java │ │ ├── ScoreExceptionHandler.java │ │ ├── Student.java │ │ ├── TaskContainer.java │ │ └── ThreadExecutor.java │ │ ├── order │ │ ├── base │ │ │ ├── event │ │ │ │ ├── AbstractEvent.java │ │ │ │ ├── OrderEvent.java │ │ │ │ └── OrderEventFactory.java │ │ │ └── handle │ │ │ │ └── AbstractEventHandler.java │ │ ├── processor │ │ │ ├── OrderProducer.java │ │ │ └── OrderThreadFactory.java │ │ └── spring │ │ │ ├── EventClient.java │ │ │ ├── IEventPublisher.java │ │ │ ├── OrderEventPublisher.java │ │ │ └── OrderSubmitEventHandler.java │ │ └── simple │ │ ├── LongEvent.java │ │ ├── LongEventFactory.java │ │ ├── LongEventHandler.java │ │ ├── LongEventProducer.java │ │ ├── LongEventProducerTranslator.java │ │ └── LongThreadFactory.java └── resources │ ├── applicationContext.xml │ └── logback.xml └── test └── java └── com └── xfboy ├── Exam_test.java ├── LongEvent_test.java ├── Order_Spring_test.java ├── Order_workpool_test.java ├── exam ├── ChooseItemProcessor.java ├── ExamTask.java ├── FillItemProcessor.java └── ZgItemProcessor.java └── order ├── Handler1.java ├── Handler2.java ├── Handler3.java ├── Handler4.java ├── Handler5.java ├── OrderWorker2Handler.java ├── OrderWorkerHandler.java └── Order_manyHandle_test.java /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/deployment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/dictionaries/Administrator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_lmax_disruptor_3_3_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__junit_junit_4_12.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_aop_4_3_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_beans_4_3_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_context_4_3_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_core_4_3_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_expression_4_3_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_test_4_3_4_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Android Lint 57 | 58 | 59 | Gradle 60 | 61 | 62 | Maven 63 | 64 | 65 | OSGi 66 | 67 | 68 | Probable bugsGradle 69 | 70 | 71 | 72 | 73 | Android 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 92 | 93 | 94 | 95 | 96 | 97 | 1.8 98 | 99 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/2/7/275d783e298228506068436512433d343feb52aa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/2/7/275d783e298228506068436512433d343feb52aa -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/2/7/27caae5bf5995d571678d8a6b02dd32944f1a381: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/2/7/27caae5bf5995d571678d8a6b02dd32944f1a381 -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/4/4/442292b8a7efeabbe4cc176709b833b1792140ec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/4/4/442292b8a7efeabbe4cc176709b833b1792140ec -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/a/e/ae5ae063b88e2ce710224b018b0fc1385937f197: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/a/e/ae5ae063b88e2ce710224b018b0fc1385937f197 -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/c/2/c23081e01bee7bfef4b275a5d060400d657ba799: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/c/2/c23081e01bee7bfef4b275a5d060400d657ba799 -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/c/3/c3fa69b85c67832f479c1aca58c38060292eebc9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/c/3/c3fa69b85c67832f479c1aca58c38060292eebc9 -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/e/0/e0d9f2fecabce341866e2d43813b1df05e205e4d: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/e/0/e0d9f2fecabce341866e2d43813b1df05e205e4d -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/e/a/ea0b9640f1eedf4c76609935aaa8f275336d991c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/e/a/ea0b9640f1eedf4c76609935aaa8f275336d991c -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/e/d/edf79a3801a6b29893cee48af21dd00c0c6839e4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/e/d/edf79a3801a6b29893cee48af21dd00c0c6839e4 -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/f/0/f016d68f06c962d3bd22c4bfc61ed5f3991514b9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex2chen/disruptor-demo/e660227036eb85a052c25b463b314ad00741d3f4/.idea/sonarlint/issuestore/f/0/f016d68f06c962d3bd22c4bfc61ed5f3991514b9 -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/index.pb: -------------------------------------------------------------------------------- 1 | 2 | 7 3 | pom.xml,4\4\442292b8a7efeabbe4cc176709b833b1792140ec 4 | 9 5 | readme.md,2\7\275d783e298228506068436512433d343feb52aa 6 | B 7 | disruptor-demo.iml,e\d\edf79a3801a6b29893cee48af21dd00c0c6839e4 8 | ` 9 | 0src\test\java\com\xfboy\Order_workpool_test.java,e\0\e0d9f2fecabce341866e2d43813b1df05e205e4d 10 | ^ 11 | .src\test\java\com\xfboy\Order_Spring_test.java,c\3\c3fa69b85c67832f479c1aca58c38060292eebc9 12 | w 13 | Gsrc\main\java\com\disruptor\order\base\handle\AbstractEventHandler.java,2\7\27caae5bf5995d571678d8a6b02dd32944f1a381 14 | h 15 | 8src\main\java\com\disruptor\simple\LongEventHandler.java,a\e\ae5ae063b88e2ce710224b018b0fc1385937f197 16 | q 17 | Asrc\main\java\com\disruptor\order\spring\OrderEventPublisher.java,c\2\c23081e01bee7bfef4b275a5d060400d657ba799 18 | [ 19 | +src\test\java\com\xfboy\LongEvent_test.java,e\a\ea0b9640f1eedf4c76609935aaa8f275336d991c 20 | V 21 | &src\test\java\com\xfboy\Exam_test.java,f\0\f016d68f06c962d3bd22c4bfc61ed5f3991514b9 -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 75 | 76 | 77 | 78 | aa 79 | 80 | 81 | 82 | 85 | 86 | 87 | 106 | 107 | 108 | 109 | 110 | true 111 | DEFINITION_ORDER 112 | 113 | 114 | 119 | 120 | 121 | 122 | 123 | 124 | 127 | 128 | 131 | 132 | 133 | 134 | 137 | 138 | 141 | 142 | 145 | 146 | 147 | 148 | 149 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 179 | 180 | 183 | 184 | 185 | 186 | 189 | 190 | 193 | 194 | 197 | 198 | 201 | 202 | 205 | 206 | 209 | 210 | 211 | 212 | 215 | 216 | 219 | 220 | 223 | 224 | 227 | 228 | 231 | 232 | 233 | 234 | 237 | 238 | 241 | 242 | 245 | 246 | 249 | 250 | 253 | 254 | 257 | 258 | 261 | 262 | 263 | 264 | 267 | 268 | 271 | 272 | 275 | 276 | 279 | 280 | 283 | 284 | 287 | 288 | 291 | 292 | 293 | 294 | 297 | 298 | 301 | 302 | 305 | 306 | 309 | 310 | 313 | 314 | 317 | 318 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 353 | 354 | 355 | 356 | 357 | 358 | 361 | 362 | 363 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 388 | 389 | 390 | 416 | 417 | 418 | 443 | 444 | 451 | 452 | 453 | 466 | 467 | 468 | 469 | 474 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 500 | 518 | 525 | 526 | 527 | 528 | 529 | 530 | 547 | 548 | 569 | 582 | 583 | 592 | 596 | 597 | 598 | 605 | 608 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 691 | 692 | 693 | 703 | 704 | 705 | 722 | 723 | 724 | 725 | 726 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 760 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 783 | 784 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 808 | 809 | 810 | 811 | 1498569847560 812 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 872 | 873 | 875 | 876 | 877 | 878 | 879 | 880 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | -------------------------------------------------------------------------------- /disruptor-demo.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /disruptor-demo.ipr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 40 | 41 | 46 | 47 | 49 | 50 | 66 | 67 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 109 | 110 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.xfboy 6 | disruptor-demo 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | disruptor-demo 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | com.lmax 20 | disruptor 21 | 3.3.6 22 | 23 | 24 | org.springframework 25 | spring-core 26 | 4.3.4.RELEASE 27 | 28 | 29 | org.springframework 30 | spring-context 31 | 4.3.4.RELEASE 32 | 33 | 34 | com.google.guava 35 | guava 36 | 21.0 37 | 38 | 39 | 40 | org.slf4j 41 | slf4j-api 42 | 1.7.12 43 | 44 | 45 | ch.qos.logback 46 | logback-core 47 | 1.1.3 48 | 49 | 50 | ch.qos.logback 51 | logback-classic 52 | 1.1.3 53 | 54 | 55 | 56 | 57 | junit 58 | junit 59 | 4.12 60 | test 61 | 62 | 63 | org.springframework 64 | spring-test 65 | 4.3.4.RELEASE 66 | 67 | 68 | 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-compiler-plugin 73 | 74 | 1.8 75 | 1.8 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ### 1.核心类和接口 2 | EventHandler:用户提供具体的实现,在里面实现事件的处理逻辑。 3 | Sequence:代表事件序号或一个指向缓存某个位置的序号。 4 | WaitStrategy:功能包括:当没有可消费的事件时,根据特定的实现进行等待,有可消费事件时返回可事件序号;有新事件发布时通知等待的 SequenceBarrier。 5 | Sequencer:生产者用于访问缓存的控制器,它持有消费者序号的引用;新事件发布后通过WaitStrategy 通知正在等待的SequenceBarrier。 6 | SequenceBarrier:消费者关卡。消费者用于访问缓存的控制器,每个访问控制器还持有前置访问控制器的引用,用于维持正确的事件处理顺序;通过WaitStrategy获取可消费事件序号。 7 | EventProcessor:事件处理器,是可执行单元,运行在指定的Executor里;它会不断地通过SequenceBarrier获取可消费事件,当有可消费事件时调用用户提供的 EventHandler实现处理事件。 8 | EventTranslator:事件转换器,由于Disruptor只会覆盖缓存,需要通过此接口的实现来更新缓存里的事件来覆盖旧事件。 9 | RingBuffer:基于数组的缓存实现,它内部持有对Executor、WaitStrategy、生产者和消费者访问控制器的引用。 10 | Disruptor:提供了对 RingBuffer 的封装,并提供了一些DSL风格的方法,方便使用。 11 | ### 2.功能 12 | #### 2.1.发布数据 13 | 1.RingBuffer.next -> Sequencer.next 这里可能会block住取决于消费端的消费速度。 14 | 2.RingBuffer.publish -> Sequencer.publish -> WaitStrategy.signalAllWhenBlocking 如果消费者在这里block住了,会通知消费者消费。 15 | #### 2.2.消费数据 16 | EventProcessor->SequenceBarrier.waitFor->EventHandler.onEvent如果消费速度赶上生产速度SequenceBarrier会把消费流程block住。 17 | Disruptor提供了两种预设的消费者,BatchEventProcessor,WorkProcessor, 18 | 区别在于BatchEventProcessor是批量读取消费,协同工作的方式是使用多个BatchEventProcessor一起消费,这种情况下每个BatchEventProcessor都是消费相同的数据,但是可以在它里面通过hash取模的方式过滤掉应该被其它线程拉取的数据 19 | 而WorkProcessor是单条消费一组WorkProcessor组成一个WorkerPool共享一个消费Sequence实现协同工作,这种工作方式因为有多个线程共享的Sequence所以违反了单写原则是有一定性能损耗的, 20 | #### 2.3.多级消费 21 | ``` 22 | // 方法1 23 | disruptor.handleEventsWithWorkerPool(parserWorkPool).then(new ThenHandler()); 24 | // 方法2 25 | SequenceBarrier sequenceBarrier = disruptorMsgBuffer.newBarrier(); 26 | batchParseProcessors[i] = new BatchEventProcessor (disruptorMsgBuffer,sequenceBarrier,handlers[i]) 27 | ``` 28 | ### 3.参数配置刨析 29 | #### 3.1.事件工厂 30 | 从名字上理解就是"事件工厂",其实它的职责就是产生数据填充RingBuffer的区块 。通过 EventFactory 在 RingBuffer 中预创建 Event 的实例,一个Event实例实际上被用作一个“数据槽”, 31 | 发布者发布前,先从RingBuffer获得一个Event的实例,然后往Event实例中填充数据,之后再发布到RingBuffer中,之后由Consumer获得该Event实例并从中读取数据。 32 | 需要实现接口 com.lmax.disruptor.EventFactory 33 | #### 3.2.ringBufferSize 34 | 大小必须是2的N 次方;目的是为了将求棋运算转为&运算提高效率 35 | #### 3.3.等待策略 36 | RingBuffer的生产都在没有可用区块(slot)的时候(可能是消费者(或者说是事件处理器)太慢了)的等待策略,定义了WaitStrategy 接口用于抽象 Consumer 如何等待新事件,根据实际运行环境的 CPU 的硬件特点选择恰当的策略,并配合特定的 JVM 的配置参数,能够实现不同的性能提升。 37 | BlockingWaitStrategy 是最低效的策略,但其对CPU的消耗最小并且在各种不同部署环境中能提供更加一致的性能表现; 38 | SleepingWaitStrategy 的性能表现跟 BlockingWaitStrategy 差不多,对 CPU 的消耗也类似,但其对生产者线程的影响最小,适合用于异步日志类似的场景; 39 | YieldingWaitStrategy 的性能是最好的,适合用于低延迟的系统。在要求极高性能且事件处理线数小于 CPU 逻辑核心数的场景中,推荐使用此策略 40 | ### 4.handleEvents和handleEventsWithWorkPool区别 41 | ##### 4.1.handleEvents 42 | 采用hanldeEvents处理多个任务时,如果注册了多个任务处理器,那么这些任务处理器会一次执行, 43 | 当然这些任务处理器要属于同一个工作组,disruptor.handleEventsWith(processors); 44 | #### 4.2.handleEventsWithWorkPool 45 | 采用handleEventsWithWorkPool处理多个任务时,如果注册了多个任务处理器,那么这些disruptor会从分组中的这些处理器中选择其中一个执行, 46 | 而不是像上面handleEvents那样每一个处理器都一次执行,(当然这些任务处理器要属于同一个工作组)disruptor.handleEventsWithWorkPool(processors); 47 | 48 | >disruptor框架中多个线程之间数据的传递是通过定义的事件绑定数据传递的 49 | 50 | #### 测试用例 51 | 该项目模拟学生考试过程,从做选择题、填空题、解答题等题型,这里的答题顺序为选择题->填空题->解答题->考试结束 52 | 53 | 54 | [Spring managed LMAX Disruptor](https://github.com/anair-it/disruptor-spring-manager) 55 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/MemoryCache.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | 4 | import com.google.common.base.Throwables; 5 | import com.google.common.collect.Maps; 6 | 7 | import java.util.concurrent.ConcurrentMap; 8 | import java.util.concurrent.locks.ReadWriteLock; 9 | import java.util.concurrent.locks.ReentrantReadWriteLock; 10 | 11 | /** 12 | * 内存缓存 13 | * 用于在并发线程中记录任务进度 14 | * 15 | * @author alex.chen 16 | * @version 1.0.0 17 | * @date 2017/6/28 18 | */ 19 | public class MemoryCache { 20 | private static MemoryCache memoryCache; 21 | private static ReadWriteLock lock = new ReentrantReadWriteLock(); 22 | private ConcurrentMap cache = Maps.newConcurrentMap(); 23 | 24 | private MemoryCache() { 25 | } 26 | 27 | public static MemoryCache getInstance() { 28 | lock.readLock().lock(); 29 | try { 30 | if (null == memoryCache) { 31 | lock.readLock().unlock(); 32 | lock.writeLock().lock(); 33 | if (null == memoryCache) { //再次检查,避免多个线程同一时刻判空创建多个memoryCache 34 | memoryCache = new MemoryCache(); 35 | } 36 | lock.readLock().lock(); // 更新锁 37 | lock.writeLock().unlock(); 38 | } 39 | } catch (Exception e) { 40 | Throwables.propagate(e); 41 | } finally { 42 | lock.readLock().unlock(); 43 | } 44 | 45 | return memoryCache; 46 | } 47 | 48 | /** 49 | * 向内存缓存中添加数据 50 | * 51 | * @param key 52 | * @param value 53 | */ 54 | public void put(String key, Object value) { 55 | cache.put(key, value); 56 | } 57 | 58 | /** 59 | * 获取内存缓存中存放的指定数据 60 | * 61 | * @param key 62 | * @return 63 | */ 64 | public Object get(String key) { 65 | return cache.get(key); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/Performer.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import com.google.common.base.Stopwatch; 4 | import com.google.common.collect.Lists; 5 | import com.lmax.disruptor.YieldingWaitStrategy; 6 | import com.lmax.disruptor.dsl.Disruptor; 7 | import com.lmax.disruptor.dsl.EventHandlerGroup; 8 | import com.lmax.disruptor.dsl.ProducerType; 9 | import com.lmax.disruptor.util.Util; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import java.util.List; 14 | import java.util.UUID; 15 | import java.util.concurrent.CountDownLatch; 16 | import java.util.concurrent.atomic.AtomicBoolean; 17 | 18 | /** 19 | * 任务执行器 20 | * 21 | * @author alex.chen 22 | * @version 1.0.0 23 | * @date 2017/6/29 24 | */ 25 | public class Performer { 26 | private static final Logger LOGGER = LoggerFactory.getLogger(Performer.class); 27 | private List processorGroups = Lists.newArrayList(); 28 | private AtomicBoolean hasError = new AtomicBoolean(false); 29 | private AtomicBoolean hasWarn = new AtomicBoolean(false); 30 | private Disruptor disruptor; 31 | private TaskContainer task; 32 | private String pid = UUID.randomUUID().toString(); 33 | 34 | public Performer(TaskContainer task) { 35 | this.task = task; 36 | } 37 | 38 | public String getPid() { 39 | return pid; 40 | } 41 | 42 | public Performer setTask(TaskContainer task) { 43 | this.task = task; 44 | return this; 45 | } 46 | 47 | public AtomicBoolean getHasError() { 48 | return hasError; 49 | } 50 | 51 | /** 52 | * 通过handleEvents处理 53 | * 54 | * @param processors 55 | * @return 56 | */ 57 | public Performer addProcessors(Processor... processors) { 58 | processorGroups.add(new ProcessorGroup().setProcessors(processors)); 59 | return this; 60 | } 61 | 62 | /** 63 | * 通过handleEventsWithWorkerPool处理 64 | * 65 | * @param processors 66 | * @return 67 | */ 68 | public Performer addProcessorPool(Processor... processors) { 69 | processorGroups.add(new ProcessorGroupPool().setProcessors(processors)); 70 | return this; 71 | } 72 | 73 | public void process() { 74 | Stopwatch stopwatch = Stopwatch.createStarted(); 75 | try { 76 | disruptor = new Disruptor(new ScoreEventFactory(), Util.ceilingNextPowerOfTwo(1024), 77 | ThreadExecutor.createThreadFactory(), ProducerType.SINGLE, new YieldingWaitStrategy()); 78 | disruptor.setDefaultExceptionHandler(new ScoreExceptionHandler(this)); 79 | //创建计数任务 80 | CountDownLatch latch = new CountDownLatch(task.getTaskCount()); 81 | //设置处理器 82 | EventHandlerGroup handlerGroup = createEventHandlerGroup(); 83 | createTaskCountHandler(handlerGroup, latch); 84 | LOGGER.debug("任务创建完成"); 85 | //启动disruptor,准备接受任务 86 | disruptor.start(); 87 | int index = 1;//当前任务索引 88 | while (task.hasNext()) { 89 | ScoreEvent event = new ScoreEvent(); 90 | event.setMessage(""); 91 | event.setProcessorContext(task.get()); 92 | event.setIndex(index++); 93 | disruptor.publishEvent(new ScoreEventTranslator(event)); 94 | } 95 | //等待任务执行完成之后再执行后续操作 96 | latch.await(); 97 | 98 | } catch (Exception ex) { 99 | LOGGER.error("发送错误,", ex); 100 | } 101 | LOGGER.debug("任务执行完毕,共耗时{}", stopwatch); 102 | } 103 | 104 | /** 105 | * 处理任务 106 | * 107 | * @return 返回任务处理分组,主要是为了后续在任务当前任务组中添加计数器任务 108 | */ 109 | private EventHandlerGroup createEventHandlerGroup() { 110 | EventHandlerGroup handlerGroup = null; 111 | ScoreEventHandler[] scoreEventHandlers = null; 112 | for (ProcessorGroup group : processorGroups) { 113 | scoreEventHandlers = toArray(group.getProcessors()); 114 | if (group instanceof ProcessorGroupPool) { 115 | if (handlerGroup == null) { 116 | handlerGroup = disruptor.handleEventsWithWorkerPool(scoreEventHandlers); 117 | } else { 118 | handlerGroup = handlerGroup.handleEventsWithWorkerPool(scoreEventHandlers); 119 | } 120 | } else { 121 | if (handlerGroup == null) { 122 | handlerGroup = disruptor.handleEventsWith(scoreEventHandlers); 123 | } else { 124 | handlerGroup = handlerGroup.handleEventsWith(scoreEventHandlers); 125 | } 126 | } 127 | } 128 | return handlerGroup; 129 | } 130 | 131 | private ScoreEventHandler[] toArray(List processors) { 132 | List handlers = Lists.newArrayList(); 133 | for (Processor processor : processors) { 134 | handlers.add(new ScoreEventHandler(processor)); 135 | } 136 | return handlers.toArray(new ScoreEventHandler[processors.size()]); 137 | } 138 | 139 | /** 140 | * 创建计数器任务,用于计数当前执行的任务数 141 | * 142 | * @param handlerGroup 143 | */ 144 | private void createTaskCountHandler(EventHandlerGroup handlerGroup, final CountDownLatch latch) { 145 | ScoreEventHandler handler = new ScoreEventHandler(new Processor() { 146 | public Class getClazz() { 147 | return ScoreEvent.class; //计数器任务标识 148 | } 149 | 150 | public void process(ScoreEvent event) { 151 | //这里-1是countDown在后面操作导致 152 | //这里开始更新进度条 153 | Progressor progressor = (Progressor) MemoryCache.getInstance().get(pid); 154 | if (progressor == null) { 155 | return; 156 | } 157 | progressor.setComplated(progressor.getComplated() + 1); 158 | if (event.isHasError()) { 159 | hasError.compareAndSet(false, true); 160 | progressor.setHasError(true); 161 | progressor.getErrorMessages().add(event.getMessage()); 162 | } 163 | 164 | if (event.isHasWarn()) { 165 | hasWarn.compareAndSet(false, true); 166 | progressor.setHasWarn(true); 167 | progressor.getWarnMessages().add(event.getMessage()); 168 | } 169 | MemoryCache.getInstance().put(pid, new Progressor(progressor.getComplated(), progressor.getTotal(), progressor.getText())); 170 | latch.countDown(); 171 | LOGGER.info("当前已经完成{},还有{}个任务...........", event.getIndex(), latch.getCount()); 172 | } 173 | }); 174 | 175 | if (handlerGroup != null) { 176 | handlerGroup.handleEventsWith(handler); 177 | } else { 178 | disruptor.handleEventsWith(handler); 179 | } 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/Processor.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | /** 4 | * 响应处理 5 | * Created by Administrator on 2017/6/29. 6 | */ 7 | public interface Processor { 8 | Class getClazz(); 9 | 10 | void process(T data); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/ProcessorContext.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import com.google.common.collect.Lists; 4 | 5 | import java.io.Serializable; 6 | import java.util.List; 7 | 8 | /** 9 | * @author alex.chen 10 | * @version 1.0.0 11 | * @date 2017/7/1 12 | */ 13 | public class ProcessorContext implements Serializable { 14 | private List students; 15 | 16 | public ProcessorContext() { 17 | students = Lists.newArrayList(); 18 | } 19 | 20 | public ProcessorContext(List students) { 21 | this.students = students; 22 | } 23 | 24 | public List getStudents() { 25 | return students; 26 | } 27 | 28 | public void setStudents(List students) { 29 | this.students = students; 30 | } 31 | 32 | public ProcessorContext addStudent(Student student) { 33 | students.add(student); 34 | return this; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "ProcessorContext{" + 40 | "students=" + students + 41 | '}'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/ProcessorGroup.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import com.google.common.base.Preconditions; 4 | import com.google.common.collect.ImmutableList; 5 | 6 | /** 7 | * 一般任务工作组 8 | * @author alex.chen 9 | * @version 1.0.0 10 | * @date 2017/6/29 11 | */ 12 | public class ProcessorGroup { 13 | private ImmutableList processors; 14 | 15 | public ImmutableList getProcessors() { 16 | return processors; 17 | } 18 | 19 | public ProcessorGroup setProcessors(ImmutableList processors) { 20 | Preconditions.checkNotNull(processors, "数据处理不能空"); 21 | this.processors = ImmutableList.copyOf(processors); 22 | return this; 23 | } 24 | 25 | public ProcessorGroup setProcessors(Processor... processors) { 26 | Preconditions.checkNotNull(processors, "数据处理不能空"); 27 | this.processors = ImmutableList.copyOf(processors); 28 | return this; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/ProcessorGroupPool.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | /** 4 | * WorkPool工作组 5 | * 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/6/29 9 | */ 10 | public class ProcessorGroupPool extends ProcessorGroup { 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/Progressor.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import com.google.common.collect.Lists; 4 | import org.springframework.util.StringUtils; 5 | 6 | import java.io.Serializable; 7 | import java.math.BigDecimal; 8 | import java.util.List; 9 | import java.util.concurrent.CopyOnWriteArrayList; 10 | 11 | /** 12 | * 任务进度,记录执行的任务进度 13 | * 前端可以用该对象信息制作进度条 14 | * 15 | * @author alex.chen 16 | * @version 1.0.0 17 | * @date 2017/6/29 18 | */ 19 | public class Progressor implements Serializable { 20 | private int total; // 任务总数 21 | private int complated; // 已经完成的任务数 22 | private double percent; // complated / total * 100 百分比分值 23 | private String text; // 进度条提示文本 24 | private boolean finished; //当前任务是否已经完成 25 | 26 | private boolean hasError = Boolean.FALSE; 27 | private boolean hasWarn = Boolean.FALSE; 28 | 29 | private CopyOnWriteArrayList errorMessages = Lists.newCopyOnWriteArrayList(); 30 | private CopyOnWriteArrayList warnMessages = Lists.newCopyOnWriteArrayList(); 31 | 32 | public Progressor(int complated, int total, String text) { 33 | this.complated = complated; 34 | this.total = total; 35 | this.text = text; 36 | 37 | this.percent = decimal(this.complated * 1.0 / this.total * 100, 2); 38 | this.finished = this.complated == this.total; 39 | } 40 | 41 | /** 42 | * 将 number保留scale小数 43 | * 44 | * @param number 45 | * @param scale 46 | * @return 47 | */ 48 | private double decimal(double number, int scale) { 49 | if (scale < 0) { 50 | scale = 0; 51 | } 52 | BigDecimal b = new BigDecimal(number); 53 | double decimal = b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 54 | return decimal; 55 | } 56 | 57 | public int getTotal() { 58 | return total; 59 | } 60 | 61 | public Progressor setTotal(int total) { 62 | this.total = total; 63 | return this; 64 | } 65 | 66 | public int getComplated() { 67 | return complated; 68 | } 69 | 70 | public Progressor setComplated(int complated) { 71 | this.complated = complated; 72 | return this; 73 | } 74 | 75 | public double getPercent() { 76 | return percent; 77 | } 78 | 79 | public Progressor setPercent(double percent) { 80 | this.percent = percent; 81 | return this; 82 | } 83 | 84 | public String getText() { 85 | return text; 86 | } 87 | 88 | public Progressor setText(String text) { 89 | this.text = text; 90 | return this; 91 | } 92 | 93 | public boolean isFinished() { 94 | return finished; 95 | } 96 | 97 | public Progressor setFinished(boolean finished) { 98 | this.finished = finished; 99 | return this; 100 | } 101 | 102 | public boolean isHasError() { 103 | return hasError; 104 | } 105 | 106 | public Progressor setHasError(boolean hasError) { 107 | this.hasError = hasError; 108 | return this; 109 | } 110 | 111 | public boolean isHasWarn() { 112 | return hasWarn; 113 | } 114 | 115 | public Progressor setHasWarn(boolean hasWarn) { 116 | this.hasWarn = hasWarn; 117 | return this; 118 | } 119 | 120 | public List getErrorMessages() { 121 | List messages = Lists.newArrayList(); 122 | messages.addAll(this.getErrorMessages()); 123 | return messages; 124 | } 125 | 126 | public List getWarnMessages() { 127 | List messages = Lists.newArrayList(); 128 | messages.addAll(this.getWarnMessages()); 129 | return warnMessages; 130 | } 131 | 132 | public Progressor addErrorMessage(String errorMessage) { 133 | if (StringUtils.hasLength(errorMessage)) { 134 | this.errorMessages.add(errorMessage); 135 | this.hasError = true; 136 | } 137 | return this; 138 | } 139 | 140 | public Progressor addWarnMessage(String warnMessage) { 141 | if (StringUtils.hasLength(warnMessage)) { 142 | this.warnMessages.add(warnMessage); 143 | this.hasWarn = true; 144 | } 145 | return this; 146 | } 147 | 148 | public Progressor addErrorMessage(List messages) { 149 | this.errorMessages.addAll(messages); 150 | if (!this.errorMessages.isEmpty()) { 151 | this.hasError = true; 152 | } 153 | return this; 154 | } 155 | 156 | public Progressor addWarnMessage(List messages) { 157 | this.warnMessages.addAll(messages); 158 | if (!this.warnMessages.isEmpty()) { 159 | this.hasWarn = true; 160 | } 161 | return this; 162 | } 163 | 164 | } 165 | 166 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/ScoreEvent.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/6/29 9 | */ 10 | public class ScoreEvent { 11 | private Object processorContext; //传递的数据对象 12 | private String message; //在任务传递过程中的一些信息,比如错误信息,警告信息等 13 | private boolean hasError = Boolean.FALSE; // 是否在执行过程中有错误 14 | private boolean hasWarn = Boolean.FALSE; //是否在执行过程中有警告信息 15 | private int index; //当前执行的任务索引号 16 | 17 | public void copy(ScoreEvent from) { 18 | this.processorContext = from.processorContext; 19 | this.index = from.index; 20 | this.hasError = false; 21 | this.hasWarn = false; 22 | message = ""; 23 | } 24 | 25 | public Object getProcessorContext() { 26 | return processorContext; 27 | } 28 | 29 | public void setProcessorContext(Object processorContext) { 30 | this.processorContext = processorContext; 31 | } 32 | 33 | public String getMessage() { 34 | return message; 35 | } 36 | 37 | public void setMessage(String message) { 38 | this.message = message; 39 | } 40 | 41 | public boolean isHasError() { 42 | return hasError; 43 | } 44 | 45 | public void setHasError(boolean hasError) { 46 | this.hasError = hasError; 47 | } 48 | 49 | public boolean isHasWarn() { 50 | return hasWarn; 51 | } 52 | 53 | public void setHasWarn(boolean hasWarn) { 54 | this.hasWarn = hasWarn; 55 | } 56 | 57 | public int getIndex() { 58 | return index; 59 | } 60 | 61 | public void setIndex(int index) { 62 | this.index = index; 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return "ScoreEvent{" + 68 | "processorContext=" + processorContext + 69 | ", message='" + message + '\'' + 70 | ", hasError=" + hasError + 71 | ", hasWarn=" + hasWarn + 72 | ", index=" + index + 73 | '}'; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/ScoreEventFactory.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import com.lmax.disruptor.EventFactory; 4 | 5 | /** 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/6/29 9 | */ 10 | public class ScoreEventFactory implements EventFactory { 11 | @Override 12 | public ScoreEvent newInstance() { 13 | return new ScoreEvent(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/ScoreEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import com.lmax.disruptor.EventHandler; 4 | import com.lmax.disruptor.WorkHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * @author alex.chen 10 | * @version 1.0.0 11 | * @date 2017/6/29 12 | */ 13 | public class ScoreEventHandler implements EventHandler, WorkHandler { 14 | private static final Logger LOGGER = LoggerFactory.getLogger(ScoreEventHandler.class); 15 | private Processor processor; 16 | 17 | public ScoreEventHandler(Processor processor) { 18 | this.processor = processor; 19 | } 20 | 21 | @Override 22 | public void onEvent(ScoreEvent scoreEvent, long l, boolean b) throws Exception { 23 | onEvent(scoreEvent); 24 | } 25 | 26 | @Override 27 | public void onEvent(ScoreEvent scoreEvent) throws Exception { 28 | if (ScoreEvent.class.equals(processor.getClazz())) { //这里表示是计数器任务,直接运行 29 | LOGGER.debug("onEvent.ScoreEvent,{}", scoreEvent); 30 | processor.process(scoreEvent); 31 | } else { 32 | //如果报错了就不在往下执行 33 | if (scoreEvent.isHasError()) { 34 | return; 35 | } 36 | LOGGER.debug("onEvent.next,{}", scoreEvent.getProcessorContext()); 37 | processor.process(scoreEvent.getProcessorContext()); //将事件中传递的数据对象往下传递执行 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/ScoreEventTranslator.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import com.lmax.disruptor.EventTranslator; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | /** 8 | * @author alex.chen 9 | * @version 1.0.0 10 | * @date 2017/6/29 11 | */ 12 | public class ScoreEventTranslator implements EventTranslator { 13 | private static final Logger LOGGER = LoggerFactory.getLogger(ScoreEventTranslator.class); 14 | private ScoreEvent event; 15 | 16 | public ScoreEventTranslator(ScoreEvent event) { 17 | this.event = event; 18 | } 19 | 20 | @Override 21 | public void translateTo(ScoreEvent scoreEvent, long l) { 22 | LOGGER.info("translateTo" + scoreEvent); 23 | scoreEvent.copy(event); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/ScoreExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import com.lmax.disruptor.ExceptionHandler; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.text.MessageFormat; 8 | 9 | /** 10 | * @author alex.chen 11 | * @version 1.0.0 12 | * @date 2017/6/29 13 | */ 14 | public class ScoreExceptionHandler implements ExceptionHandler { 15 | private static final Logger LOGGER = LoggerFactory.getLogger(ScoreExceptionHandler.class); 16 | private Performer performer; 17 | 18 | public ScoreExceptionHandler(Performer performer) { 19 | this.performer = performer; 20 | } 21 | 22 | public void handleEventException(Throwable throwable, long l, ScoreEvent event) { 23 | performer.getHasError().compareAndSet(false, true); 24 | String message = MessageFormat.format("处理{0}数据出错", event.getProcessorContext().toString()); 25 | LOGGER.error("错误,cause:" + throwable.getMessage(), throwable); 26 | event.setHasError(true); 27 | event.setMessage(message); 28 | } 29 | 30 | public void handleOnStartException(Throwable throwable) { 31 | LOGGER.error("启动disruptor出错,cause:" + throwable.getMessage(), throwable); 32 | } 33 | 34 | public void handleOnShutdownException(Throwable throwable) { 35 | LOGGER.error("关闭disruptor出错,cause:" + throwable.getMessage(), throwable); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/Student.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/7/1 9 | */ 10 | public class Student implements Serializable { 11 | private String name; 12 | 13 | public Student() { 14 | } 15 | 16 | public Student(String name) { 17 | this.name = name; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "Student{" + 31 | "name='" + name + '\'' + 32 | '}'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/TaskContainer.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import com.google.common.collect.Lists; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author alex.chen 9 | * @version 1.0.0 10 | * @date 2017/6/29 11 | */ 12 | public abstract class TaskContainer { 13 | protected int index = 0; 14 | protected T current = null; 15 | protected List tasks = Lists.newArrayList(); 16 | 17 | public TaskContainer(List tasks) { 18 | this.tasks = tasks; 19 | } 20 | public boolean hasNext() { 21 | try { 22 | current = tasks.get(index++); 23 | return true; 24 | } catch (Exception e) { 25 | return false; 26 | } 27 | } 28 | public T next() { 29 | return current; 30 | } 31 | public int getTaskCount() { 32 | return tasks.size(); 33 | } 34 | 35 | /** 36 | * 每个任务执行中需要传递的实际数据对象 37 | * 该对象由当前任务中的cur和不同任务需要的其他数据封装而成 38 | * 39 | * @return 40 | */ 41 | public abstract Object get(); 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/exam/ThreadExecutor.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.exam; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | /** 7 | * @author alex.chen 8 | * @version 1.0.0 9 | * @date 2017/6/29 10 | */ 11 | public class ThreadExecutor { 12 | private static AtomicInteger poolNo = new AtomicInteger(0); 13 | 14 | public static ThreadFactory createThreadFactory() { 15 | ThreadFactory factory = new ThreadFactory() { 16 | public Thread newThread(Runnable r) { 17 | SecurityManager manager = System.getSecurityManager(); 18 | ThreadGroup group = manager != null ? manager.getThreadGroup() : Thread.currentThread().getThreadGroup(); 19 | Thread thread = new Thread(group, r, "Thread-disruptor-" + poolNo.getAndIncrement() + "-"); 20 | if (thread.isDaemon()) { 21 | thread.setDaemon(Boolean.FALSE); 22 | } 23 | if (thread.getPriority() != Thread.NORM_PRIORITY) { 24 | thread.setPriority(Thread.NORM_PRIORITY); 25 | } 26 | return thread; 27 | } 28 | }; 29 | 30 | return factory; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/base/event/AbstractEvent.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.base.event; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/6/27 9 | */ 10 | public abstract class AbstractEvent implements Serializable { 11 | private int source; 12 | 13 | public int getSource() { 14 | return source; 15 | } 16 | 17 | public void setSource(int source) { 18 | this.source = source; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/base/event/OrderEvent.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.base.event; 2 | 3 | /** 4 | * @author alex.chen 5 | * @version 1.0.0 6 | * @date 2017/6/27 7 | */ 8 | public class OrderEvent extends AbstractEvent { 9 | private String orderId; 10 | private String orderType; 11 | private double orderFee; 12 | 13 | public String getOrderId() { 14 | return orderId; 15 | } 16 | 17 | public void setOrderId(String orderId) { 18 | this.orderId = orderId; 19 | } 20 | 21 | public String getOrderType() { 22 | return orderType; 23 | } 24 | 25 | public void setOrderType(String orderType) { 26 | this.orderType = orderType; 27 | } 28 | 29 | public double getOrderFee() { 30 | return orderFee; 31 | } 32 | 33 | public void setOrderFee(double orderFee) { 34 | this.orderFee = orderFee; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "OrderEvent{" + 40 | "orderId='" + orderId + '\'' + 41 | ", orderType='" + orderType + '\'' + 42 | ", orderFee=" + orderFee + 43 | '}'; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/base/event/OrderEventFactory.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.base.event; 2 | 3 | import com.lmax.disruptor.EventFactory; 4 | 5 | /** 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/6/29 9 | */ 10 | public class OrderEventFactory implements EventFactory { 11 | @Override 12 | public OrderEvent newInstance() { 13 | return new OrderEvent(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/base/handle/AbstractEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.base.handle; 2 | 3 | import com.disruptor.order.base.event.AbstractEvent; 4 | import com.lmax.disruptor.EventHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * @author alex.chen 10 | * @version 1.0.0 11 | * @date 2017/6/27 12 | */ 13 | public abstract class AbstractEventHandler implements EventHandler { 14 | private static final Logger LOGGER = LoggerFactory.getLogger(AbstractEventHandler.class); 15 | 16 | public void onEvent(AbstractEvent event, long sequence, boolean endOfBatch) throws Exception { 17 | if (preBusiness(event) && doCondition(event)) { 18 | onEvent(event); 19 | } 20 | } 21 | 22 | private void onEvent(AbstractEvent event) { 23 | LOGGER.debug("成功消费," + event); 24 | } 25 | 26 | protected abstract boolean doCondition(AbstractEvent event); 27 | 28 | protected abstract boolean preBusiness(AbstractEvent event); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/processor/OrderProducer.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.processor; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.lmax.disruptor.EventTranslator; 5 | import com.lmax.disruptor.RingBuffer; 6 | 7 | /** 8 | * @author alex.chen 9 | * @version 1.0.0 10 | * @date 2017/6/29 11 | */ 12 | public class OrderProducer implements EventTranslator { 13 | private RingBuffer ringBuffer; 14 | 15 | public OrderProducer(RingBuffer ringBuffer) { 16 | this.ringBuffer = ringBuffer; 17 | } 18 | 19 | public void translateTo(OrderEvent order, long l) { 20 | order.setOrderId("1"); 21 | order.setOrderType("订单"); 22 | order.setOrderFee(2); 23 | } 24 | 25 | public void onData() { 26 | ringBuffer.publishEvent(this); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/processor/OrderThreadFactory.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.processor; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | 5 | /** 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/6/29 9 | */ 10 | public class OrderThreadFactory implements ThreadFactory { 11 | 12 | public Thread newThread(Runnable r) { 13 | // TODO Auto-generated method stub 14 | return new Thread(r); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/spring/EventClient.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.spring; 2 | 3 | import com.disruptor.order.base.event.AbstractEvent; 4 | import org.springframework.beans.BeansException; 5 | import org.springframework.context.ApplicationContext; 6 | import org.springframework.context.ApplicationContextAware; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.util.StringUtils; 9 | 10 | /** 11 | * @author alex.chen 12 | * @version 1.0.0 13 | * @date 2017/6/27 14 | */ 15 | @Component 16 | public class EventClient implements ApplicationContextAware { 17 | private ApplicationContext applicationContext; 18 | 19 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 20 | this.applicationContext = applicationContext; 21 | } 22 | 23 | public void publish(AbstractEvent event) { 24 | String eventName = StringUtils.uncapitalize(event.getClass().getSimpleName()); 25 | IEventPublisher publisher = (IEventPublisher) applicationContext.getBean(eventName + "Publisher"); 26 | if (publisher != null) { 27 | publisher.publish(event); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/spring/IEventPublisher.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.spring; 2 | 3 | import com.disruptor.order.base.event.AbstractEvent; 4 | 5 | /** 6 | * Created by Administrator on 2017/6/27. 7 | */ 8 | public interface IEventPublisher { 9 | void publish(T event); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/spring/OrderEventPublisher.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.spring; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.lmax.disruptor.BlockingWaitStrategy; 5 | import com.lmax.disruptor.EventFactory; 6 | import com.lmax.disruptor.EventTranslatorOneArg; 7 | import com.lmax.disruptor.RingBuffer; 8 | import com.lmax.disruptor.dsl.Disruptor; 9 | import com.lmax.disruptor.dsl.ProducerType; 10 | import org.springframework.beans.factory.InitializingBean; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.concurrent.Executors; 14 | 15 | /** 16 | * @author alex.chen 17 | * @version 1.0.0 18 | * @date 2017/6/27 19 | */ 20 | @Component 21 | public class OrderEventPublisher implements IEventPublisher, InitializingBean { 22 | private Disruptor disruptor; 23 | private static final EventTranslatorOneArg translator = new 24 | EventTranslatorOneArg() { 25 | public void translateTo(OrderEvent event, long sequence, OrderEvent arg0) { 26 | // event = arg0;//为毛不能这个要深刻理解 27 | event.setOrderId(arg0.getOrderId()); 28 | } 29 | }; 30 | 31 | public void publish(OrderEvent event) { 32 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 33 | ringBuffer.tryPublishEvent(translator, event);//发布事件; 34 | } 35 | 36 | public void afterPropertiesSet() throws Exception { 37 | disruptor = new Disruptor(new EventFactory() { 38 | public OrderEvent newInstance() { 39 | return new OrderEvent(); 40 | } 41 | }, 1024, Executors.newFixedThreadPool(10), ProducerType.MULTI, new BlockingWaitStrategy()); 42 | disruptor.handleEventsWith(new OrderSubmitEventHandler()); 43 | disruptor.start(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/order/spring/OrderSubmitEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.order.spring; 2 | 3 | 4 | import com.disruptor.order.base.event.AbstractEvent; 5 | import com.disruptor.order.base.handle.AbstractEventHandler; 6 | 7 | /** 8 | * @author alex.chen 9 | * @version 1.0.0 10 | * @date 2017/6/27 11 | */ 12 | public class OrderSubmitEventHandler extends AbstractEventHandler { 13 | 14 | protected boolean doCondition(AbstractEvent event) { 15 | return true; 16 | } 17 | 18 | protected boolean preBusiness(AbstractEvent event) { 19 | return true; 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/com/disruptor/simple/LongEvent.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.simple; 2 | 3 | /** 4 | * 定义事件 5 | * 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/6/29 9 | */ 10 | public class LongEvent { 11 | private long value; 12 | 13 | public long getValue() { 14 | return value; 15 | } 16 | 17 | public void setValue(long value) { 18 | this.value = value; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "LongEvent{" + 24 | "value=" + value + 25 | '}'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/simple/LongEventFactory.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.simple; 2 | 3 | import com.lmax.disruptor.EventFactory; 4 | 5 | /** 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/6/29 9 | */ 10 | public class LongEventFactory implements EventFactory { 11 | public LongEvent newInstance() { 12 | return new LongEvent(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/simple/LongEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.simple; 2 | 3 | import com.lmax.disruptor.EventHandler; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | /** 8 | * 事件处理的具体实现 9 | * 10 | * @author alex.chen 11 | * @version 1.0.0 12 | * @date 2017/6/29 13 | */ 14 | public class LongEventHandler implements EventHandler { 15 | private static final Logger LOGGER = LoggerFactory.getLogger(LongEventHandler.class); 16 | 17 | public void onEvent(LongEvent event, long sequence, boolean endOfBatch) throws Exception { 18 | LOGGER.debug("完成消费,Event: " + event); 19 | // throw new RuntimeException("error"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/simple/LongEventProducer.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.simple; 2 | 3 | import com.lmax.disruptor.RingBuffer; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | /** 8 | * @author alex.chen 9 | * @version 1.0.0 10 | * @date 2017/6/29 11 | */ 12 | public class LongEventProducer { 13 | private RingBuffer ringBuffer; 14 | 15 | public LongEventProducer(RingBuffer ringBuffer) { 16 | this.ringBuffer = ringBuffer; 17 | } 18 | 19 | /** 20 | * onData用来发布事件,每调用一次就发布一次事件 它的参数会用过事件传递给消费者 21 | */ 22 | public void onData(ByteBuffer bb) { 23 | // 1.可以把ringBuffer看做一个事件队列,那么next就是得到下面一个事件槽 24 | long sequence = ringBuffer.next(); 25 | try { 26 | // 2.用上面的索引取出一个空的事件用于填充(获取该序号对应的事件对象) 27 | LongEvent event = ringBuffer.get(sequence); 28 | // 3.获取要通过事件传递的业务数据 29 | event.setValue(bb.getLong(0)); 30 | } catch (Exception e) { 31 | // TODO Auto-generated catch block 32 | e.printStackTrace(); 33 | } finally { 34 | // 4.发布事件 35 | // 注意,最后的 ringBuffer.publish 方法必须包含在 finally 中以确保必须得到调用;如果某个请求的 sequence 未被提交 36 | ringBuffer.publish(sequence); 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/simple/LongEventProducerTranslator.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.simple; 2 | 3 | import com.lmax.disruptor.EventTranslatorOneArg; 4 | import com.lmax.disruptor.RingBuffer; 5 | 6 | import java.nio.ByteBuffer; 7 | 8 | /** 9 | * @author alex.chen 10 | * @version 1.0.0 11 | * @date 2017/6/29 12 | */ 13 | public class LongEventProducerTranslator implements EventTranslatorOneArg { 14 | private RingBuffer ringBuffer; 15 | 16 | public LongEventProducerTranslator(RingBuffer ringBuffer) { 17 | this.ringBuffer = ringBuffer; 18 | } 19 | 20 | public void translateTo(LongEvent longEvent, long l, ByteBuffer data) { 21 | longEvent.setValue(data.getLong(0)); 22 | } 23 | public void onData(ByteBuffer bb) { 24 | ringBuffer.publishEvent(this, bb); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/disruptor/simple/LongThreadFactory.java: -------------------------------------------------------------------------------- 1 | package com.disruptor.simple; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | 5 | /** 6 | * @author alex.chen 7 | * @version 1.0.0 8 | * @date 2017/6/29 9 | */ 10 | public class LongThreadFactory implements ThreadFactory { 11 | public Thread newThread(Runnable r) { 12 | return new Thread(r); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}[%L]: %msg%n 8 | 9 | System.out 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/Exam_test.java: -------------------------------------------------------------------------------- 1 | package com.xfboy; 2 | 3 | import com.disruptor.exam.MemoryCache; 4 | import com.disruptor.exam.Performer; 5 | import com.disruptor.exam.Progressor; 6 | import com.disruptor.exam.Student; 7 | import com.google.common.collect.Lists; 8 | import com.google.common.collect.Maps; 9 | import com.lmax.disruptor.util.Util; 10 | import com.xfboy.exam.ChooseItemProcessor; 11 | import com.xfboy.exam.ExamTask; 12 | import com.xfboy.exam.FillItemProcessor; 13 | import com.xfboy.exam.ZgItemProcessor; 14 | import org.junit.Assert; 15 | import org.junit.Before; 16 | import org.junit.Test; 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | 20 | import java.util.List; 21 | import java.util.Map; 22 | import java.util.concurrent.ConcurrentMap; 23 | import java.util.concurrent.CountDownLatch; 24 | 25 | /** 26 | * @author alex.chen 27 | * @version 1.0.0 28 | * @date 2017/6/29 29 | */ 30 | public class Exam_test { 31 | private Logger logger = LoggerFactory.getLogger(Exam_test.class); 32 | 33 | private List students; 34 | 35 | @Before 36 | public void initData() { 37 | students = Lists.newArrayList(); 38 | students.add(new Student("alex")); 39 | students.add(new Student("lisa")); 40 | } 41 | 42 | @Test 43 | public void go_MemoryCache() throws Exception { 44 | final ConcurrentMap map = Maps.newConcurrentMap(); 45 | final CountDownLatch latch = new CountDownLatch(100); 46 | for (int i = 0; i < 100; i++) { 47 | final int finalI = i; 48 | new Thread(new Runnable() { 49 | public void run() { 50 | map.put(MemoryCache.getInstance(), finalI); 51 | latch.countDown(); 52 | } 53 | }).start(); 54 | } 55 | 56 | latch.await(); 57 | 58 | System.out.println(map.keySet().size()); 59 | for (Object key : map.keySet()) { 60 | System.out.println(key + ":" + map.get(key)); 61 | } 62 | } 63 | 64 | @Test 65 | public void go_ceilingNextPowerOfTwo() { 66 | Assert.assertTrue(Util.ceilingNextPowerOfTwo(3) % 2 == 0); 67 | Assert.assertTrue(Util.ceilingNextPowerOfTwo(1024) % 2 == 0); 68 | } 69 | 70 | @Test 71 | public void go_handleEventsWith() { 72 | ExamTask task = new ExamTask(students); 73 | //Choose>Fill>Zg>Choose>ScoreEvent 74 | Performer performer = new Performer(task); 75 | performer.addProcessors(new ChooseItemProcessor()) 76 | .addProcessors(new FillItemProcessor()) 77 | .addProcessors(new ZgItemProcessor(), new ChooseItemProcessor()); 78 | MemoryCache.getInstance().put(performer.getPid(), new Progressor(0, task.getTaskCount(), "准备执行任务...")); 79 | performer.process(); 80 | //初始化进度条 81 | logger.info("考试结束..."); 82 | } 83 | 84 | @Test 85 | public void go_handleEventsWithWorkerPool() { 86 | ExamTask task = new ExamTask(students); 87 | Performer performer = new Performer(task); 88 | performer.addProcessorPool(new ChooseItemProcessor(), new ChooseItemProcessor()) 89 | .addProcessorPool(new FillItemProcessor(), new ChooseItemProcessor()) 90 | .addProcessorPool(new ZgItemProcessor(), new ChooseItemProcessor()); 91 | MemoryCache.getInstance().put(performer.getPid(), new Progressor(0, task.getTaskCount(), "准备执行任务...")); 92 | performer.process(); 93 | Progressor progressor = (Progressor) MemoryCache.getInstance().get(performer.getPid()); 94 | System.out.println(progressor.getTotal() + "," + progressor.getComplated() + "," + progressor.isFinished()); 95 | //初始化进度条 96 | logger.info("考试结束..."); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/LongEvent_test.java: -------------------------------------------------------------------------------- 1 | package com.xfboy; 2 | 3 | import com.disruptor.simple.*; 4 | import com.google.common.base.Stopwatch; 5 | import com.lmax.disruptor.EventFactory; 6 | import com.lmax.disruptor.RingBuffer; 7 | import com.lmax.disruptor.YieldingWaitStrategy; 8 | import com.lmax.disruptor.dsl.Disruptor; 9 | import com.lmax.disruptor.dsl.ProducerType; 10 | import org.junit.Test; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.io.IOException; 15 | import java.nio.ByteBuffer; 16 | import java.util.concurrent.ExecutorService; 17 | import java.util.concurrent.Executors; 18 | 19 | /** 20 | * @author alex.chen 21 | * @version 1.0.0 22 | * @date 2017/6/29 23 | */ 24 | public class LongEvent_test { 25 | private static final Logger LOGGER = LoggerFactory.getLogger(LongEvent_test.class); 26 | 27 | @Test 28 | public void go_Long_PublishEvent() throws IOException { 29 | Stopwatch stopwatch = Stopwatch.createStarted(); 30 | Disruptor disruptor = getDisruptor(false); 31 | // 发布事件 32 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 33 | long sequence = ringBuffer.next();//请求下一个事件序号; 34 | try { 35 | LongEvent event = ringBuffer.get(sequence);//获取该序号对应的事件对象; 36 | event.setValue(123); 37 | } finally { 38 | /* 39 | 注意,最后的 ringBuffer.publish 方法必须包含在 finally 中以确保必须得到调用; 40 | 如果某个请求的 sequence 未被提交,将会堵塞后续的发布操作或者其它的 producer。 41 | */ 42 | ringBuffer.publish(sequence);//发布事件; 43 | } 44 | //关闭 Disruptor 45 | //disruptor.shutdown();//关闭 disruptor,方法会堵塞,直至所有的事件都得到处理; 46 | //executor.shutdown();//关闭 disruptor 使用的线程池;如果需要的话,必须手动关闭, disruptor 在 shutdown 时不会自动关闭; 47 | disruptor.halt(); 48 | LOGGER.debug("任务执行完毕,共耗时{}", stopwatch); 49 | //System.in.read(); 50 | } 51 | 52 | @Test 53 | public void go_Long_PublishEvent2() throws IOException { 54 | Disruptor disruptor = getDisruptor(false); 55 | // 发布事件; 56 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 57 | final LongEventProducerTranslator TRANSLATOR = new LongEventProducerTranslator(ringBuffer); 58 | /** 59 | * Disruptor要求RingBuffer.publishEvent 必须得到调用的潜台词就是,如果发生异常也一样要调用 publish , 60 | * 那么,很显然这个时候需要调用者在事件处理的实现上来判断事件携带的数据是否是正确的或者完整的,这是实现者应该要注意的事情。 61 | */ 62 | ByteBuffer buffer = ByteBuffer.allocate(8); 63 | buffer.putLong(0, 456L); 64 | ringBuffer.publishEvent(TRANSLATOR, buffer); 65 | disruptor.shutdown(); 66 | System.in.read(); 67 | } 68 | 69 | @Test 70 | public void go_LongProducer() throws IOException { 71 | Disruptor disruptor = getDisruptor(true); 72 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 73 | LongEventProducerTranslator producer = new LongEventProducerTranslator(ringBuffer); 74 | ByteBuffer buffer = ByteBuffer.allocate(8); 75 | for (int i = 0; i < 10; i++) { 76 | buffer.putLong(0, Long.valueOf(i + "")); 77 | producer.onData(buffer); 78 | } 79 | disruptor.shutdown(); 80 | System.in.read(); 81 | } 82 | 83 | private Disruptor getDisruptor(boolean enabledThreadFaction) { 84 | //实例化Disruptor 85 | EventFactory eventFactory = new LongEventFactory(); 86 | ExecutorService executor = Executors.newSingleThreadExecutor(); 87 | int ringBufferSize = 1024 * 1024; // ringBufferSize 大小,必须是 2 的 N 次方; 88 | Disruptor disruptor = null; 89 | if (enabledThreadFaction) { 90 | disruptor = new Disruptor(eventFactory, ringBufferSize, new LongThreadFactory(), 91 | ProducerType.SINGLE, new YieldingWaitStrategy()); 92 | 93 | } else { 94 | disruptor = new Disruptor(eventFactory, ringBufferSize, executor, ProducerType.SINGLE, 95 | new YieldingWaitStrategy()); 96 | } 97 | disruptor.handleEventsWith(new LongEventHandler()); 98 | //启动 99 | disruptor.start(); 100 | return disruptor; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/Order_Spring_test.java: -------------------------------------------------------------------------------- 1 | package com.xfboy; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.disruptor.order.spring.EventClient; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.test.context.ContextConfiguration; 9 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 10 | 11 | import java.io.IOException; 12 | import java.util.UUID; 13 | 14 | /** 15 | * @author alex.chen 16 | * @version 1.0.0 17 | * @date 2017/6/27 18 | */ 19 | @RunWith(SpringJUnit4ClassRunner.class) 20 | @ContextConfiguration(locations = {"classpath*:applicationContext.xml"}) 21 | public class Order_Spring_test { 22 | @Autowired 23 | private EventClient eventClient; 24 | 25 | @Test 26 | public void OrderEventPublishTest() throws IOException { 27 | OrderEvent orderEvent = new OrderEvent(); 28 | orderEvent.setOrderId(UUID.randomUUID().toString()); 29 | orderEvent.setOrderType("jd"); 30 | orderEvent.setOrderFee(199); 31 | eventClient.publish(orderEvent); 32 | System.in.read(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/Order_workpool_test.java: -------------------------------------------------------------------------------- 1 | package com.xfboy; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.disruptor.order.base.event.OrderEventFactory; 5 | import com.disruptor.order.processor.OrderProducer; 6 | import com.lmax.disruptor.*; 7 | import com.xfboy.order.OrderWorker2Handler; 8 | import com.xfboy.order.OrderWorkerHandler; 9 | import org.junit.Test; 10 | 11 | import java.util.concurrent.ExecutorService; 12 | import java.util.concurrent.Executors; 13 | 14 | /** 15 | * @author alex.chen 16 | * @version 1.0.0 17 | * @date 2017/6/29 18 | */ 19 | public class Order_workpool_test { 20 | 21 | @Test 22 | public void go_workpool() { 23 | RingBuffer ringBuffer = RingBuffer.createSingleProducer(new OrderEventFactory(), 1024 * 1024); 24 | SequenceBarrier sequenceBarrier = ringBuffer.newBarrier(); 25 | WorkHandler[] workHandlers = new WorkHandler[2]; 26 | workHandlers[0] = new OrderWorkerHandler(); 27 | workHandlers[1] = new OrderWorker2Handler(); 28 | WorkerPool workerPool = new WorkerPool(ringBuffer, sequenceBarrier, new IgnoreExceptionHandler(), workHandlers); 29 | // 这一步的目的就是把消费者的位置信息引用注入到生产者 如果只有一个消费者的情况可以省略 30 | ringBuffer.addGatingSequences(workerPool.getWorkerSequences()); 31 | ExecutorService executor = Executors.newFixedThreadPool(10); 32 | workerPool.start(executor); 33 | 34 | OrderProducer orderProducer = new OrderProducer(ringBuffer); 35 | orderProducer.onData(); 36 | orderProducer.onData(); 37 | orderProducer.onData(); 38 | orderProducer.onData(); 39 | try { 40 | Thread.sleep(1000); 41 | } catch (InterruptedException e) { 42 | // TODO Auto-generated catch block 43 | e.printStackTrace(); 44 | } 45 | // 通知事件(或者说消息)处理器 可以结束了(并不是马上结束!!!) 46 | workerPool.halt(); 47 | executor.shutdown(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/exam/ChooseItemProcessor.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.exam; 2 | 3 | import com.disruptor.exam.Processor; 4 | import com.disruptor.exam.ProcessorContext; 5 | import com.disruptor.exam.Student; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.stream.Collector; 12 | import java.util.stream.Collectors; 13 | 14 | /** 15 | * @author alex.chen 16 | * @version 1.0.0 17 | * @date 2017/6/29 18 | */ 19 | public class ChooseItemProcessor implements Processor { 20 | private static final Logger logger = LoggerFactory.getLogger(ChooseItemProcessor.class); 21 | 22 | @Override 23 | public Class getClazz() { 24 | return ProcessorContext.class; 25 | } 26 | 27 | @Override 28 | public void process(ProcessorContext data) { 29 | List students = data.getStudents(); 30 | if (students != null && !students.isEmpty()) 31 | logger.info(students.stream().map(Student::getName).collect(Collectors.joining()) + "开始做选择题..."); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/exam/ExamTask.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.exam; 2 | 3 | import com.disruptor.exam.ProcessorContext; 4 | import com.disruptor.exam.Student; 5 | import com.disruptor.exam.TaskContainer; 6 | import com.google.common.collect.Lists; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author alex.chen 13 | * @version 1.0.0 14 | * @date 2017/6/29 15 | */ 16 | public class ExamTask extends TaskContainer { 17 | public ExamTask(List students) { 18 | super(students); 19 | } 20 | 21 | @Override 22 | public Object get() { 23 | return new ProcessorContext().addStudent(current); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/exam/FillItemProcessor.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.exam; 2 | 3 | import com.disruptor.exam.Processor; 4 | import com.disruptor.exam.ProcessorContext; 5 | import com.disruptor.exam.Student; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.stream.Collectors; 12 | 13 | /** 14 | * @author alex.chen 15 | * @version 1.0.0 16 | * @date 2017/6/29 17 | */ 18 | public class FillItemProcessor implements Processor { 19 | private static final Logger logger = LoggerFactory.getLogger(FillItemProcessor.class); 20 | 21 | @Override 22 | public Class getClazz() { 23 | return ProcessorContext.class; 24 | } 25 | 26 | @Override 27 | public void process(ProcessorContext data) { 28 | List students = data.getStudents(); 29 | if (students != null && !students.isEmpty()) 30 | logger.info(students.stream().map(Student::getName).collect(Collectors.joining()) + "开始做填空题..."); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/exam/ZgItemProcessor.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.exam; 2 | 3 | import com.disruptor.exam.Processor; 4 | import com.disruptor.exam.ProcessorContext; 5 | import com.disruptor.exam.Student; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.stream.Collectors; 12 | 13 | /** 14 | * @author alex.chen 15 | * @version 1.0.0 16 | * @date 2017/6/29 17 | */ 18 | public class ZgItemProcessor implements Processor { 19 | private static final Logger logger = LoggerFactory.getLogger(ZgItemProcessor.class); 20 | 21 | @Override 22 | public Class getClazz() { 23 | return ProcessorContext.class; 24 | } 25 | 26 | @Override 27 | public void process(ProcessorContext data) { 28 | List students = data.getStudents(); 29 | if (students != null && !students.isEmpty()) 30 | logger.info(students.stream().map(Student::getName).collect(Collectors.joining()) + "开始做解答题..."); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/order/Handler1.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.order; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.lmax.disruptor.EventHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class Handler1 implements EventHandler { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(Handler1.class); 10 | public void onEvent(OrderEvent order, long paramLong, boolean paramBoolean) throws Exception { 11 | LOGGER.debug("handler1 set name"); 12 | order.setOrderType("order-h1"); 13 | Thread.sleep(1000); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/order/Handler2.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.order; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.lmax.disruptor.EventHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class Handler2 implements EventHandler { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(Handler2.class); 10 | public void onEvent(OrderEvent order, long paramLong, boolean paramBoolean) throws Exception { 11 | LOGGER.debug("hanlder2 set price"); 12 | order.setOrderFee(200); 13 | Thread.sleep(1000); 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/order/Handler3.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.order; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.lmax.disruptor.EventHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class Handler3 implements EventHandler { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(Handler3.class); 10 | 11 | public void onEvent(OrderEvent order, long paramLong, boolean paramBoolean) throws Exception { 12 | LOGGER.debug("hanlder3 getOrder :" + order); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/order/Handler4.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.order; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.lmax.disruptor.EventHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class Handler4 implements EventHandler { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(Handler4.class); 10 | public void onEvent(OrderEvent order, long paramLong, boolean paramBoolean) throws Exception { 11 | LOGGER.debug("handler4 get name :" + order.getOrderType()); 12 | order.setOrderType(order.getOrderType() + "-h4"); 13 | Thread.sleep(1000); 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/order/Handler5.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.order; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.lmax.disruptor.EventHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class Handler5 implements EventHandler { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(Handler5.class); 10 | 11 | public void onEvent(OrderEvent order, long paramLong, boolean paramBoolean) throws Exception { 12 | LOGGER.debug("handler5 get price :" + order.getOrderFee()); 13 | order.setOrderFee(order.getOrderFee() + 100); 14 | Thread.sleep(1000); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/order/OrderWorker2Handler.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.order; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.lmax.disruptor.WorkHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * @author alex.chen 10 | * @version 1.0.0 11 | * @date 2017/6/29 12 | */ 13 | public class OrderWorker2Handler implements WorkHandler { 14 | private static final Logger LOGGER = LoggerFactory.getLogger(OrderWorker2Handler.class); 15 | 16 | @Override 17 | public void onEvent(OrderEvent order) throws Exception { 18 | LOGGER.debug("成功消费:" + order); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/order/OrderWorkerHandler.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.order; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.lmax.disruptor.WorkHandler; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * @author alex.chen 10 | * @version 1.0.0 11 | * @date 2017/6/29 12 | */ 13 | public class OrderWorkerHandler implements WorkHandler { 14 | private static final Logger LOGGER = LoggerFactory.getLogger(OrderWorkerHandler.class); 15 | 16 | @Override 17 | public void onEvent(OrderEvent order) throws Exception { 18 | LOGGER.debug("成功消费:" + order); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/xfboy/order/Order_manyHandle_test.java: -------------------------------------------------------------------------------- 1 | package com.xfboy.order; 2 | 3 | import com.disruptor.order.base.event.OrderEvent; 4 | import com.disruptor.order.base.event.OrderEventFactory; 5 | import com.disruptor.order.processor.OrderProducer; 6 | import com.disruptor.order.processor.OrderThreadFactory; 7 | import com.lmax.disruptor.RingBuffer; 8 | import com.lmax.disruptor.YieldingWaitStrategy; 9 | import com.lmax.disruptor.dsl.Disruptor; 10 | import com.lmax.disruptor.dsl.EventHandlerGroup; 11 | import com.lmax.disruptor.dsl.ProducerType; 12 | import com.lmax.disruptor.util.Util; 13 | import org.junit.Test; 14 | 15 | import java.io.IOException; 16 | 17 | /** 18 | * @author alex.chen 19 | * @version 1.0.0 20 | * @date 2017/6/29 21 | */ 22 | public class Order_manyHandle_test { 23 | private OrderEventFactory eventFactory = new OrderEventFactory(); 24 | 25 | // handler1和Handler2并行消费,handler1和hanlder3消费完,再轮到handler3消费 26 | @Test 27 | public void go_ConcurrentRun() throws IOException { 28 | Disruptor disruptor = new Disruptor(eventFactory, Util.ceilingNextPowerOfTwo(1024), new OrderThreadFactory(), 29 | ProducerType.SINGLE, new YieldingWaitStrategy()); 30 | EventHandlerGroup group = disruptor.handleEventsWith(new Handler1(), new Handler2()); 31 | group.then(new Handler3()); 32 | disruptor.start(); 33 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 34 | OrderProducer producer = new OrderProducer(ringBuffer); 35 | producer.onData(); 36 | System.in.read(); 37 | } 38 | 39 | //按handler1,handler2,handler3顺序消费 40 | @Test 41 | public void go_SortRun() throws IOException { 42 | Disruptor disruptor = new Disruptor(eventFactory, Util.ceilingNextPowerOfTwo(1024), new OrderThreadFactory(), 43 | ProducerType.SINGLE, new YieldingWaitStrategy()); 44 | disruptor.handleEventsWith(new Handler1()); 45 | disruptor.handleEventsWith(new Handler2()); 46 | disruptor.handleEventsWith(new Handler3()); 47 | disruptor.start(); 48 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 49 | OrderProducer producer = new OrderProducer(ringBuffer); 50 | producer.onData(); 51 | System.in.read(); 52 | } 53 | 54 | // 六边形消费 55 | // handler1,handler2并行消费,handler1消费后,轮到handler4消费,hangler2消费完轮到handler5消费,hangler4和handler5消费完,最后轮到handler3消费 56 | @Test 57 | public void go_SexangleRun() { 58 | Disruptor disruptor = new Disruptor(eventFactory, Util.ceilingNextPowerOfTwo(1024 * 1024), new OrderThreadFactory(), 59 | ProducerType.SINGLE, new YieldingWaitStrategy()); 60 | Handler1 handler1 = new Handler1(); 61 | Handler2 handler2 = new Handler2(); 62 | Handler3 handler3 = new Handler3(); 63 | Handler4 handler4 = new Handler4(); 64 | Handler5 handler5 = new Handler5(); 65 | disruptor.handleEventsWith(handler1, handler2); 66 | disruptor.after(handler1).handleEventsWith(handler4); 67 | disruptor.after(handler2).handleEventsWith(handler5); 68 | disruptor.after(handler4, handler5).handleEventsWith(handler3); 69 | disruptor.start(); 70 | 71 | RingBuffer ringBuffer = disruptor.getRingBuffer(); 72 | OrderProducer producer = new OrderProducer(ringBuffer); 73 | producer.onData(); 74 | try { 75 | Thread.sleep(2000); 76 | } catch (InterruptedException e) { 77 | // TODO Auto-generated catch block 78 | e.printStackTrace(); 79 | } 80 | disruptor.shutdown(); 81 | } 82 | } 83 | --------------------------------------------------------------------------------