├── .idea
├── compiler.xml
├── encodings.xml
├── misc.xml
├── vcs.xml
└── workspace.xml
├── Disruptor.md
├── JMH.md
├── JUC.iml
├── README.md
├── pom.xml
├── src
└── main
│ ├── java
│ ├── com
│ │ └── mashibing
│ │ │ ├── JustTest.java
│ │ │ ├── Tets.java
│ │ │ ├── disruptor
│ │ │ ├── v1
│ │ │ │ ├── LongEvent.java
│ │ │ │ ├── LongEventFactory.java
│ │ │ │ ├── LongEventHandler.java
│ │ │ │ ├── LongEventProducer.java
│ │ │ │ └── Main.java
│ │ │ ├── v2
│ │ │ │ ├── LongEvent.java
│ │ │ │ ├── LongEventFactory.java
│ │ │ │ ├── LongEventHandler.java
│ │ │ │ ├── LongEventProducer.java
│ │ │ │ ├── Main.java
│ │ │ │ └── readme
│ │ │ ├── v3
│ │ │ │ ├── LongEvent.java
│ │ │ │ ├── Main.java
│ │ │ │ └── readme
│ │ │ └── v4
│ │ │ │ ├── LongEvent.java
│ │ │ │ ├── Main.java
│ │ │ │ └── readme
│ │ │ └── juc
│ │ │ ├── c_000
│ │ │ ├── T01_WhatIsThread.java
│ │ │ ├── T02_HowToCreateThread.java
│ │ │ ├── T03_Sleep_Yield_Join.java
│ │ │ └── T04_ThreadState.java
│ │ │ ├── c_001
│ │ │ └── T.java
│ │ │ ├── c_002
│ │ │ └── T.java
│ │ │ ├── c_003
│ │ │ ├── T.java
│ │ │ └── T1.java
│ │ │ ├── c_004
│ │ │ └── T.java
│ │ │ ├── c_005
│ │ │ └── T.java
│ │ │ ├── c_006
│ │ │ └── T.java
│ │ │ ├── c_007
│ │ │ └── T.java
│ │ │ ├── c_008
│ │ │ └── Account.java
│ │ │ ├── c_009
│ │ │ └── T.java
│ │ │ ├── c_010
│ │ │ └── T.java
│ │ │ ├── c_011
│ │ │ └── T.java
│ │ │ ├── c_011_01
│ │ │ └── readme
│ │ │ ├── c_012_Volatile
│ │ │ ├── T01_HelloVolatile.java
│ │ │ ├── T02_VolatileReference1.java
│ │ │ ├── T03________VolatileReference2.java
│ │ │ ├── T04_VolatileNotSync.java
│ │ │ └── T05_VolatileVsSync.java
│ │ │ ├── c_016_LockOptimization
│ │ │ └── FineCoarseLock.java
│ │ │ ├── c_017_MoreAboutSync
│ │ │ ├── DoNotLockString.java
│ │ │ └── SyncSameObject.java
│ │ │ ├── c_018_00_AtomicXXX
│ │ │ ├── T01_AtomicInteger.java
│ │ │ ├── T02_AtomicVsSyncVsLongAdder.java
│ │ │ └── T03________SyncVsLongAdder.java
│ │ │ ├── c_018_01_Unsafe
│ │ │ └── HelloUnsafe.java
│ │ │ ├── c_020
│ │ │ ├── T01_ReentrantLock1.java
│ │ │ ├── T02_ReentrantLock2.java
│ │ │ ├── T03_ReentrantLock3.java
│ │ │ ├── T04_ReentrantLock4.java
│ │ │ ├── T05_ReentrantLock5.java
│ │ │ ├── T06_TestCountDownLatch.java
│ │ │ ├── T07_TestCyclicBarrier.java
│ │ │ ├── T08_TestPhaser.java
│ │ │ ├── T09_TestPhaser2.java
│ │ │ ├── T10_TestReadWriteLock.java
│ │ │ ├── T11_TestSemaphore.java
│ │ │ ├── T12_TestExchanger.java
│ │ │ └── T13_TestLockSupport.java
│ │ │ ├── c_020_01_Interview
│ │ │ ├── T01_WithoutVolatile.java
│ │ │ ├── T02_WithVolatile.java
│ │ │ ├── T03_NotifyHoldingLock.java
│ │ │ ├── T04_NotifyFreeLock.java
│ │ │ ├── T05_CountDownLatch.java
│ │ │ ├── T06_LockSupport.java
│ │ │ ├── T07_LockSupport_WithoutSleep.java
│ │ │ └── T08_Semaphore.java
│ │ │ ├── c_021_01_interview
│ │ │ ├── MyContainer1.java
│ │ │ └── MyContainer2.java
│ │ │ ├── c_021_02_AQS
│ │ │ ├── MLock.java
│ │ │ ├── Main.java
│ │ │ ├── Sync.java
│ │ │ └── TestReentrantLock.java
│ │ │ ├── c_021_03_VarHandle
│ │ │ └── T01_HelloVarHandle.java
│ │ │ ├── c_022_RefTypeAndThreadLocal
│ │ │ ├── M.java
│ │ │ ├── T01_NormalReference.java
│ │ │ ├── T02_SoftReference.java
│ │ │ ├── T03_WeakReference.java
│ │ │ ├── T04_PhantomReference.java
│ │ │ ├── ThreadLocal1.java
│ │ │ └── ThreadLocal2.java
│ │ │ ├── c_023
│ │ │ └── Singleton.java
│ │ │ ├── c_023_01_Containers
│ │ │ ├── HelloQueue.java
│ │ │ ├── T01_HelloArray.java
│ │ │ └── T02_CollectionListSetQueue.java
│ │ │ ├── c_023_02_FromHashtableToCHM
│ │ │ ├── Constants.java
│ │ │ ├── T01_TestHashtable.java
│ │ │ ├── T02_TestHashMap.java
│ │ │ ├── T03_TestSynchronizedHashMap.java
│ │ │ └── T04_TestConcurrentHashMap.java
│ │ │ ├── c_024_FromVectorToQueue
│ │ │ ├── TicketSeller1.java
│ │ │ ├── TicketSeller2.java
│ │ │ ├── TicketSeller3.java
│ │ │ ├── TicketSeller4.java
│ │ │ └── readme.txt
│ │ │ ├── c_025
│ │ │ ├── T01_ConcurrentMap.java
│ │ │ ├── T02_CopyOnWriteList.java
│ │ │ ├── T03_SynchronizedList.java
│ │ │ ├── T04_ConcurrentQueue.java
│ │ │ ├── T05_LinkedBlockingQueue.java
│ │ │ ├── T06_ArrayBlockingQueue.java
│ │ │ ├── T07_01_PriorityQueque.java
│ │ │ ├── T07_DelayQueue.java
│ │ │ ├── T08_SynchronusQueue.java
│ │ │ ├── T09_TransferQueue.java
│ │ │ └── readme.txt
│ │ │ ├── c_026_00_interview
│ │ │ └── A1B2C3
│ │ │ │ ├── T01_00_Question.java
│ │ │ │ ├── T02_00_LockSupport.java
│ │ │ │ ├── T03_00_cas.java
│ │ │ │ ├── T04_00_BlockingQueue.java
│ │ │ │ ├── T05_00_AtomicInteger.java
│ │ │ │ ├── T06_00_sync_wait_notify.java
│ │ │ │ ├── T07_00_sync_wait_notify.java
│ │ │ │ ├── T08_00_lock_condition.java
│ │ │ │ ├── T09_00_lock_condition.java
│ │ │ │ ├── T10_00_PipedStream.java
│ │ │ │ ├── T12_00_Exchanger_Not_Work.java
│ │ │ │ ├── T13_TransferQueue.java
│ │ │ │ └── readme
│ │ │ ├── c_026_01_ThreadPool
│ │ │ ├── T01_MyExecutor.java
│ │ │ ├── T02_ExecutorService.java
│ │ │ ├── T03_Callable.java
│ │ │ ├── T04_Executors.java
│ │ │ ├── T05_00_HelloThreadPool.java
│ │ │ ├── T05_ThreadPool.java
│ │ │ ├── T06_00_Future.java
│ │ │ ├── T06_01_CompletableFuture.java
│ │ │ ├── T07_SingleThreadPool.java
│ │ │ ├── T08_CachedPool.java
│ │ │ ├── T09_FixedThreadPool.java
│ │ │ ├── T10_ScheduledPool.java
│ │ │ ├── T11_WorkStealingPool.java
│ │ │ ├── T12_ForkJoinPool.java
│ │ │ ├── T13_ParallelStreamAPI.java
│ │ │ ├── T14_MyRejectedHandler.java
│ │ │ ├── ThreadPoolExecutor源码解析.md
│ │ │ └── readme.txt
│ │ │ ├── c_027_future_to_loom
│ │ │ ├── T01_Future.java
│ │ │ └── T02_ListenableFuture.java
│ │ │ ├── c_028_FalseSharing
│ │ │ ├── T01_CacheLinePadding.java
│ │ │ └── T02_CacheLinePadding.java
│ │ │ └── c_029_WriteCombining
│ │ │ └── WriteCombining.java
│ └── 思考题.txt
│ └── resources
│ └── Test.puml
└── target
└── classes
├── META-INF
└── JUC.kotlin_module
└── Test.puml
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/encodings.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 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.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 | synchronized
123 | compare
124 | incrementand
125 | compareandset
126 | all
127 | sun.mi
128 | onadv
129 | set
130 | synchronizedMap
131 | synchronizedList
132 | Fork
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
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 | 1565232818446
385 |
386 |
387 | 1565232818446
388 |
389 |
390 | 1566616292953
391 |
392 |
393 |
394 | 1566616292953
395 |
396 |
397 | 1567908240513
398 |
399 |
400 |
401 | 1567908240513
402 |
403 |
404 | 1569205605236
405 |
406 |
407 |
408 | 1569205605236
409 |
410 |
411 | 1569727444423
412 |
413 |
414 |
415 | 1569727444423
416 |
417 |
418 | 1570803022734
419 |
420 |
421 |
422 | 1570803022735
423 |
424 |
425 | 1571235524344
426 |
427 |
428 |
429 | 1571235524344
430 |
431 |
432 | 1573357300351
433 |
434 |
435 |
436 | 1573357300351
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 | file://$PROJECT_DIR$/src/main/java/com/mashibing/juc/c_020/T11_TestSemaphore.java
513 | 12
514 |
515 |
516 |
517 |
518 | jar://C:/Program Files/Java/jdk-11.0.3/lib/src.zip!/java.base/java/util/concurrent/locks/ReentrantLock.java
519 | 126
520 |
521 |
522 |
523 |
524 | file://$PROJECT_DIR$/src/main/java/com/mashibing/juc/c_021_02_AQS/TestReentrantLock.java
525 | 10
526 |
527 |
528 |
529 |
530 | jar://C:/Program Files/Java/jdk1.7.0_80/src.zip!/java/util/concurrent/ConcurrentHashMap.java
531 | 807
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
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 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
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 | No facets are configured
944 |
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
954 |
955 |
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 |
965 |
966 | 11
967 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 | JUC
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
988 |
989 |
990 | Maven: com.lmax:disruptor:3.4.2
991 |
992 |
993 |
994 |
995 |
996 |
997 |
998 |
999 |
1000 |
1001 |
1002 |
--------------------------------------------------------------------------------
/Disruptor.md:
--------------------------------------------------------------------------------
1 | # Disruptor
2 |
3 | 作者:马士兵 http://www.mashibing.com
4 |
5 | 最近更新:2019年10月22日
6 |
7 | ## 介绍
8 |
9 | 主页:http://lmax-exchange.github.io/disruptor/
10 |
11 | 源码:https://github.com/LMAX-Exchange/disruptor
12 |
13 | GettingStarted: https://github.com/LMAX-Exchange/disruptor/wiki/Getting-Started
14 |
15 | api: http://lmax-exchange.github.io/disruptor/docs/index.html
16 |
17 | maven: https://mvnrepository.com/artifact/com.lmax/disruptor
18 |
19 | ## Disruptor的特点
20 |
21 | 对比ConcurrentLinkedQueue : 链表实现
22 |
23 | JDK中没有ConcurrentArrayQueue
24 |
25 | Disruptor是数组实现的
26 |
27 | 无锁,高并发,使用环形Buffer,直接覆盖(不用清除)旧的数据,降低GC频率
28 |
29 | 实现了基于事件的生产者消费者模式(观察者模式)
30 |
31 | ## RingBuffer
32 |
33 | 环形队列
34 |
35 | RingBuffer的序号,指向下一个可用的元素
36 |
37 | 采用数组实现,没有首尾指针
38 |
39 | 对比ConcurrentLinkedQueue,用数组实现的速度更快
40 |
41 | > 假如长度为8,当添加到第12个元素的时候在哪个序号上呢?用12%8决定
42 | >
43 | > 当Buffer被填满的时候到底是覆盖还是等待,由Producer决定
44 | >
45 | > 长度设为2的n次幂,利于二进制计算,例如:12%8 = 12 & (8 - 1) pos = num & (size -1)
46 |
47 | ## Disruptor开发步骤
48 |
49 | 1. 定义Event - 队列中需要处理的元素
50 |
51 | 2. 定义Event工厂,用于填充队列
52 |
53 | > 这里牵扯到效率问题:disruptor初始化的时候,会调用Event工厂,对ringBuffer进行内存的提前分配
54 | >
55 | > GC产频率会降低
56 |
57 | 3. 定义EventHandler(消费者),处理容器中的元素
58 |
59 | ## 事件发布模板
60 |
61 | ```java
62 | long sequence = ringBuffer.next(); // Grab the next sequence
63 | try {
64 | LongEvent event = ringBuffer.get(sequence); // Get the entry in the Disruptor
65 | // for the sequence
66 | event.set(8888L); // Fill with data
67 | } finally {
68 | ringBuffer.publish(sequence);
69 | }
70 | ```
71 |
72 | ## 使用EventTranslator发布事件
73 |
74 | ```java
75 | //===============================================================
76 | EventTranslator translator1 = new EventTranslator() {
77 | @Override
78 | public void translateTo(LongEvent event, long sequence) {
79 | event.set(8888L);
80 | }
81 | };
82 |
83 | ringBuffer.publishEvent(translator1);
84 |
85 | //===============================================================
86 | EventTranslatorOneArg translator2 = new EventTranslatorOneArg() {
87 | @Override
88 | public void translateTo(LongEvent event, long sequence, Long l) {
89 | event.set(l);
90 | }
91 | };
92 |
93 | ringBuffer.publishEvent(translator2, 7777L);
94 |
95 | //===============================================================
96 | EventTranslatorTwoArg translator3 = new EventTranslatorTwoArg() {
97 | @Override
98 | public void translateTo(LongEvent event, long sequence, Long l1, Long l2) {
99 | event.set(l1 + l2);
100 | }
101 | };
102 |
103 | ringBuffer.publishEvent(translator3, 10000L, 10000L);
104 |
105 | //===============================================================
106 | EventTranslatorThreeArg translator4 = new EventTranslatorThreeArg() {
107 | @Override
108 | public void translateTo(LongEvent event, long sequence, Long l1, Long l2, Long l3) {
109 | event.set(l1 + l2 + l3);
110 | }
111 | };
112 |
113 | ringBuffer.publishEvent(translator4, 10000L, 10000L, 1000L);
114 |
115 | //===============================================================
116 | EventTranslatorVararg translator5 = new EventTranslatorVararg() {
117 |
118 | @Override
119 | public void translateTo(LongEvent event, long sequence, Object... objects) {
120 | long result = 0;
121 | for(Object o : objects) {
122 | long l = (Long)o;
123 | result += l;
124 | }
125 | event.set(result);
126 | }
127 | };
128 |
129 | ringBuffer.publishEvent(translator5, 10000L, 10000L, 10000L, 10000L);
130 | ```
131 |
132 | ## 使用Lamda表达式
133 |
134 | ```java
135 | package com.mashibing.disruptor;
136 |
137 | import com.lmax.disruptor.RingBuffer;
138 | import com.lmax.disruptor.dsl.Disruptor;
139 | import com.lmax.disruptor.util.DaemonThreadFactory;
140 |
141 | public class Main03
142 | {
143 | public static void main(String[] args) throws Exception
144 | {
145 | // Specify the size of the ring buffer, must be power of 2.
146 | int bufferSize = 1024;
147 |
148 | // Construct the Disruptor
149 | Disruptor disruptor = new Disruptor<>(LongEvent::new, bufferSize, DaemonThreadFactory.INSTANCE);
150 |
151 | // Connect the handler
152 | disruptor.handleEventsWith((event, sequence, endOfBatch) -> System.out.println("Event: " + event));
153 |
154 | // Start the Disruptor, starts all threads running
155 | disruptor.start();
156 |
157 | // Get the ring buffer from the Disruptor to be used for publishing.
158 | RingBuffer ringBuffer = disruptor.getRingBuffer();
159 |
160 |
161 | ringBuffer.publishEvent((event, sequence) -> event.set(10000L));
162 |
163 | System.in.read();
164 | }
165 | }
166 | ```
167 |
168 | ## ProducerType生产者线程模式
169 |
170 | > ProducerType有两种模式 Producer.MULTI和Producer.SINGLE
171 | >
172 | > 默认是MULTI,表示在多线程模式下产生sequence
173 | >
174 | > 如果确认是单线程生产者,那么可以指定SINGLE,效率会提升
175 | >
176 | > 如果是多个生产者(多线程),但模式指定为SINGLE,会出什么问题呢?
177 |
178 | ## 等待策略
179 |
180 | 1,(常用)BlockingWaitStrategy:通过线程阻塞的方式,等待生产者唤醒,被唤醒后,再循环检查依赖的sequence是否已经消费。
181 |
182 | 2,BusySpinWaitStrategy:线程一直自旋等待,可能比较耗cpu
183 |
184 | 3,LiteBlockingWaitStrategy:线程阻塞等待生产者唤醒,与BlockingWaitStrategy相比,区别在signalNeeded.getAndSet,如果两个线程同时访问一个访问waitfor,一个访问signalAll时,可以减少lock加锁次数.
185 |
186 | 4,LiteTimeoutBlockingWaitStrategy:与LiteBlockingWaitStrategy相比,设置了阻塞时间,超过时间后抛异常。
187 |
188 | 5,PhasedBackoffWaitStrategy:根据时间参数和传入的等待策略来决定使用哪种等待策略
189 |
190 | 6,TimeoutBlockingWaitStrategy:相对于BlockingWaitStrategy来说,设置了等待时间,超过后抛异常
191 |
192 | 7,(常用)YieldingWaitStrategy:尝试100次,然后Thread.yield()让出cpu
193 |
194 | 8. (常用)SleepingWaitStrategy : sleep
195 |
196 | ## 消费者异常处理
197 |
198 | 默认:disruptor.setDefaultExceptionHandler()
199 |
200 | 覆盖:disruptor.handleExceptionFor().with()
201 |
202 | ## 依赖处理
203 |
204 |
--------------------------------------------------------------------------------
/JMH.md:
--------------------------------------------------------------------------------
1 | # JMH Java准测试工具套件
2 |
3 | ## 什么是JMH
4 |
5 | ### 官网
6 |
7 | http://openjdk.java.net/projects/code-tools/jmh/
8 |
9 | ## 创建JMH测试
10 |
11 | 1. 创建Maven项目,添加依赖
12 |
13 | ```java
14 |
15 |
18 | 4.0.0
19 |
20 |
21 | UTF-8
22 | UTF-8
23 | 1.8
24 | 1.8
25 | 1.8
26 |
27 |
28 | mashibing.com
29 | HelloJMH2
30 | 1.0-SNAPSHOT
31 |
32 |
33 |
34 |
35 |
36 | org.openjdk.jmh
37 | jmh-core
38 | 1.21
39 |
40 |
41 |
42 |
43 | org.openjdk.jmh
44 | jmh-generator-annprocess
45 | 1.21
46 | test
47 |
48 |
49 |
50 |
51 |
52 | ```
53 |
54 | 2. idea安装JMH插件 JMH plugin v1.0.3
55 |
56 | 3. 由于用到了注解,打开运行程序注解配置
57 |
58 | > compiler -> Annotation Processors -> Enable Annotation Processing
59 |
60 | 4. 定义需要测试类PS (ParallelStream)
61 |
62 | ```java
63 | package com.mashibing.jmh;
64 |
65 | import java.util.ArrayList;
66 | import java.util.List;
67 | import java.util.Random;
68 |
69 | public class PS {
70 |
71 | static List nums = new ArrayList<>();
72 | static {
73 | Random r = new Random();
74 | for (int i = 0; i < 10000; i++) nums.add(1000000 + r.nextInt(1000000));
75 | }
76 |
77 | static void foreach() {
78 | nums.forEach(v->isPrime(v));
79 | }
80 |
81 | static void parallel() {
82 | nums.parallelStream().forEach(PS::isPrime);
83 | }
84 |
85 | static boolean isPrime(int num) {
86 | for(int i=2; i<=num/2; i++) {
87 | if(num % i == 0) return false;
88 | }
89 | return true;
90 | }
91 | }
92 | ```
93 |
94 | 5. 写单元测试
95 |
96 | > 这个测试类一定要在test package下面
97 | >
98 | > ```java
99 | > package com.mashibing.jmh;
100 | >
101 | > import org.openjdk.jmh.annotations.Benchmark;
102 | >
103 | > import static org.junit.jupiter.api.Assertions.*;
104 | >
105 | > public class PSTest {
106 | > @Benchmark
107 | > public void testForEach() {
108 | > PS.foreach();
109 | > }
110 | > }
111 | > ```
112 |
113 | 6. 运行测试类,如果遇到下面的错误:
114 |
115 | ```java
116 | ERROR: org.openjdk.jmh.runner.RunnerException: ERROR: Exception while trying to acquire the JMH lock (C:\WINDOWS\/jmh.lock): C:\WINDOWS\jmh.lock (拒绝访问。), exiting. Use -Djmh.ignoreLock=true to forcefully continue.
117 | at org.openjdk.jmh.runner.Runner.run(Runner.java:216)
118 | at org.openjdk.jmh.Main.main(Main.java:71)
119 | ```
120 |
121 | 这个错误是因为JMH运行需要访问系统的TMP目录,解决办法是:
122 |
123 | 打开RunConfiguration -> Environment Variables -> include system environment viables
124 |
125 | 7. 阅读测试报告
126 |
127 | ## JMH中的基本概念
128 |
129 | 1. Warmup
130 | 预热,由于JVM中对于特定代码会存在优化(本地化),预热对于测试结果很重要
131 | 2. Mesurement
132 | 总共执行多少次测试
133 | 3. Timeout
134 |
135 | 4. Threads
136 | 线程数,由fork指定
137 | 5. Benchmark mode
138 | 基准测试的模式
139 | 6. Benchmark
140 | 测试哪一段代码
141 |
142 | ## Next
143 |
144 | 官方样例:
145 | http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/
146 |
147 |
--------------------------------------------------------------------------------
/JUC.iml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JUC
2 | 多线程与高并发
3 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | mashibing.com
8 | JUC
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 1.8
13 | 1.8
14 |
15 |
16 |
17 |
18 |
19 | com.google.guava
20 | guava
21 | 28.0-jre
22 |
23 |
24 |
25 | com.lmax
26 | disruptor
27 | 3.4.2
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/JustTest.java:
--------------------------------------------------------------------------------
1 | package com.mashibing;
2 |
3 | public class JustTest {
4 | public static void main(String[] args) {
5 | Object o = new Object();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/Tets.java:
--------------------------------------------------------------------------------
1 | package com.mashibing;
2 |
3 | import java.util.concurrent.ConcurrentHashMap;
4 |
5 | public class Tets {
6 | public static void main(String[] args) {
7 | ConcurrentHashMap map = new ConcurrentHashMap();
8 | map.put("1", "msb");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v1/LongEvent.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v1;
2 |
3 | public class LongEvent {
4 | private long value;
5 |
6 | public long getValue() {
7 | return value;
8 | }
9 |
10 | public void setValue(long value) {
11 | this.value = value;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v1/LongEventFactory.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v1;
2 |
3 | import com.lmax.disruptor.EventFactory;
4 |
5 | public class LongEventFactory implements EventFactory {
6 |
7 | public LongEvent newInstance() {
8 | return new LongEvent();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v1/LongEventHandler.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v1;
2 |
3 | import com.lmax.disruptor.EventHandler;
4 |
5 | public class LongEventHandler implements EventHandler {
6 | public void onEvent(LongEvent longEvent, long l, boolean b) throws Exception {
7 | System.out.println(longEvent.getValue());
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v1/LongEventProducer.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v1;
2 |
3 | import com.lmax.disruptor.RingBuffer;
4 |
5 | import java.nio.ByteBuffer;
6 |
7 | public class LongEventProducer {
8 | private final RingBuffer ringBuffer;
9 |
10 | public LongEventProducer(RingBuffer ringBuffer) {
11 | this.ringBuffer = ringBuffer;
12 | }
13 |
14 | public void onData(ByteBuffer buffer) {
15 | long sequence = ringBuffer.next();
16 | try {
17 | LongEvent event = ringBuffer.get(sequence);
18 | event.setValue(buffer.getLong(0));
19 | } finally {
20 | ringBuffer.publish(sequence);
21 | }
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v1/Main.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v1;
2 |
3 | import com.lmax.disruptor.RingBuffer;
4 | import com.lmax.disruptor.dsl.Disruptor;
5 |
6 | import java.nio.ByteBuffer;
7 | import java.util.concurrent.Executor;
8 | import java.util.concurrent.Executors;
9 |
10 | public class Main {
11 | public static void main(String[] args) {
12 | //Executor executor = Executors.newCachedThreadPool();
13 |
14 | LongEventFactory factory = new LongEventFactory();
15 |
16 | //must be power of 2
17 | int ringBufferSize = 1024;
18 |
19 | Disruptor disruptor = new Disruptor(factory, ringBufferSize, Executors.defaultThreadFactory());
20 |
21 | disruptor.handleEventsWith(new LongEventHandler());
22 |
23 | disruptor.start();
24 |
25 | RingBuffer ringBuffer = disruptor.getRingBuffer();
26 |
27 | LongEventProducer producer = new LongEventProducer(ringBuffer);
28 |
29 | ByteBuffer bb = ByteBuffer.allocate(8);
30 |
31 | for(long l = 0; l<100; l++) {
32 | bb.putLong(0, l);
33 |
34 | producer.onData(bb);
35 |
36 | try {
37 | Thread.sleep(100);
38 | } catch (InterruptedException e) {
39 | e.printStackTrace();
40 | }
41 | }
42 |
43 | disruptor.shutdown();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v2/LongEvent.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v2;
2 |
3 | public class LongEvent {
4 | private long value;
5 |
6 | public long getValue() {
7 | return value;
8 | }
9 |
10 | public void setValue(long value) {
11 | this.value = value;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v2/LongEventFactory.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v2;
2 |
3 | import com.lmax.disruptor.EventFactory;
4 |
5 | public class LongEventFactory implements EventFactory {
6 |
7 | public LongEvent newInstance() {
8 | return new LongEvent();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v2/LongEventHandler.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v2;
2 |
3 | import com.lmax.disruptor.EventHandler;
4 |
5 | public class LongEventHandler implements EventHandler {
6 | public void onEvent(LongEvent longEvent, long l, boolean b) throws Exception {
7 | System.out.println(longEvent.getValue());
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v2/LongEventProducer.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v2;
2 |
3 | import com.lmax.disruptor.EventTranslator;
4 | import com.lmax.disruptor.EventTranslatorOneArg;
5 | import com.lmax.disruptor.RingBuffer;
6 |
7 | import java.nio.ByteBuffer;
8 |
9 | public class LongEventProducer {
10 | private final RingBuffer ringBuffer;
11 |
12 | private static final EventTranslatorOneArg TRANSLATOR = new EventTranslatorOneArg() {
13 | @Override
14 | public void translateTo(LongEvent event, long sequence, ByteBuffer bb) {
15 | event.setValue(bb.getLong(0));
16 | }
17 | };
18 |
19 | public LongEventProducer(RingBuffer ringBuffer) {
20 | this.ringBuffer = ringBuffer;
21 | }
22 |
23 | public void onData(ByteBuffer buffer) {
24 | ringBuffer.publishEvent(TRANSLATOR, buffer);
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v2/Main.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v2;
2 |
3 | import com.lmax.disruptor.RingBuffer;
4 | import com.lmax.disruptor.dsl.Disruptor;
5 |
6 | import java.nio.ByteBuffer;
7 | import java.util.concurrent.Executor;
8 | import java.util.concurrent.ExecutorService;
9 | import java.util.concurrent.Executors;
10 |
11 | public class Main {
12 | public static void main(String[] args) {
13 | //ExecutorService executor = Executors.newCachedThreadPool();
14 |
15 | LongEventFactory factory = new LongEventFactory();
16 |
17 | //must be power of 2
18 | int ringBufferSize = 1024;
19 |
20 | Disruptor disruptor = new Disruptor(factory, ringBufferSize, Executors.defaultThreadFactory());
21 |
22 | disruptor.handleEventsWith(new LongEventHandler());
23 |
24 | disruptor.start();
25 |
26 | RingBuffer ringBuffer = disruptor.getRingBuffer();
27 |
28 | LongEventProducer producer = new LongEventProducer(ringBuffer);
29 |
30 | ByteBuffer bb = ByteBuffer.allocate(8);
31 |
32 | for(long l = 0; true; l++) {
33 | bb.putLong(0, 1);
34 |
35 | producer.onData(bb);
36 |
37 | try {
38 | Thread.sleep(100);
39 | } catch (InterruptedException e) {
40 | e.printStackTrace();
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v2/readme:
--------------------------------------------------------------------------------
1 | 修改LongEventProducer
2 | 将事件的发布过程封装到EventTranslator
3 | 减少了对于ringbuffer的直接操作
4 | 同时可以将Translator单独出来,方便进行单元测试
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v3/LongEvent.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v3;
2 |
3 | public class LongEvent {
4 | private long value;
5 |
6 | public long getValue() {
7 | return value;
8 | }
9 |
10 | public void setValue(long value) {
11 | this.value = value;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v3/Main.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v3;
2 |
3 | import com.lmax.disruptor.EventHandler;
4 | import com.lmax.disruptor.RingBuffer;
5 | import com.lmax.disruptor.dsl.Disruptor;
6 | import com.lmax.disruptor.util.DaemonThreadFactory;
7 |
8 | import java.nio.ByteBuffer;
9 | import java.util.concurrent.Executors;
10 |
11 | public class Main {
12 | public static void main(String[] args) {
13 | int bufferSize = 1024;
14 |
15 | // Construct the Disruptor
16 | Disruptor disruptor = new Disruptor<>(LongEvent::new, bufferSize, DaemonThreadFactory.INSTANCE);
17 |
18 | // Connect the handler
19 | disruptor.handleEventsWith((event, sequence, endOfBatch) -> System.out.println(event.getValue()));
20 |
21 | // Start the Disruptor, starts all threads running
22 | disruptor.start();
23 |
24 | // Get the ring buffer from the Disruptor to be used for publishing.
25 | RingBuffer ringBuffer = disruptor.getRingBuffer();
26 |
27 | ByteBuffer bb = ByteBuffer.allocate(8);
28 | for (long l = 0; true; l++)
29 | {
30 | bb.putLong(0, l);
31 | ringBuffer.publishEvent((event, sequence, buffer) -> event.setValue(buffer.getLong(0)), bb);
32 |
33 | //ringBuffer.publishEvent((event, sequence) -> event.setValue(bb.getLong(0)));
34 |
35 | try {
36 | Thread.sleep(1000);
37 | } catch (InterruptedException e) {
38 | e.printStackTrace();
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v3/readme:
--------------------------------------------------------------------------------
1 | 修改Main,使用LambdaAPI
2 | 不再使用LongEventFactory 改用LongEvent::new
3 |
4 | 不推荐下面这种写法
5 | ringBuffer.publishEvent((event, sequence) -> event.setValue(bb.getLong(0)));
6 |
7 | 原因是这是一个capturing lambda, 每一个lamda会产生一个对象来承接bb,这样会产生大量的小对象
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v4/LongEvent.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v4;
2 |
3 | public class LongEvent {
4 | private long value;
5 |
6 | public long getValue() {
7 | return value;
8 | }
9 |
10 | public void setValue(long value) {
11 | this.value = value;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v4/Main.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.disruptor.v4;
2 |
3 | import com.lmax.disruptor.RingBuffer;
4 | import com.lmax.disruptor.dsl.Disruptor;
5 | import com.lmax.disruptor.util.DaemonThreadFactory;
6 |
7 | import java.nio.ByteBuffer;
8 |
9 | public class Main {
10 |
11 | public static void handleEvent(LongEvent event, long sequence, boolean endOfBatch)
12 | {
13 | System.out.println(event);
14 | }
15 |
16 | public static void translate(LongEvent event, long sequence, ByteBuffer buffer)
17 | {
18 | event.setValue(buffer.getLong(0));
19 | }
20 |
21 | public static void main(String[] args) throws Exception
22 | {
23 | // Specify the size of the ring buffer, must be power of 2.
24 | int bufferSize = 1024;
25 |
26 | // Construct the Disruptor
27 | Disruptor disruptor = new Disruptor<>(LongEvent::new, bufferSize, DaemonThreadFactory.INSTANCE);
28 |
29 | // Connect the handler
30 | disruptor.handleEventsWith(Main::handleEvent);
31 |
32 | // Start the Disruptor, starts all threads running
33 | disruptor.start();
34 |
35 | // Get the ring buffer from the Disruptor to be used for publishing.
36 | RingBuffer ringBuffer = disruptor.getRingBuffer();
37 |
38 | ByteBuffer bb = ByteBuffer.allocate(8);
39 | for (long l = 0; true; l++)
40 | {
41 | bb.putLong(0, l);
42 | ringBuffer.publishEvent(Main::translate, bb);
43 | Thread.sleep(1000);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/disruptor/v4/readme:
--------------------------------------------------------------------------------
1 | 最好的写法
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_000/T01_WhatIsThread.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_000;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | public class T01_WhatIsThread {
6 | private static class T1 extends Thread {
7 | @Override
8 | public void run() {
9 | for(int i=0; i<10; i++) {
10 | try {
11 | TimeUnit.MICROSECONDS.sleep(1);
12 | } catch (InterruptedException e) {
13 | e.printStackTrace();
14 | }
15 | System.out.println("T1");
16 | }
17 | }
18 | }
19 |
20 | public static void main(String[] args) {
21 | //new T1().run();
22 | new T1().start();
23 | for(int i=0; i<10; i++) {
24 | try {
25 | TimeUnit.MICROSECONDS.sleep(1);
26 | } catch (InterruptedException e) {
27 | e.printStackTrace();
28 | }
29 | System.out.println("main");
30 | }
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_000/T02_HowToCreateThread.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_000;
2 |
3 | public class T02_HowToCreateThread {
4 | static class MyThread extends Thread {
5 | @Override
6 | public void run() {
7 | System.out.println("Hello MyThread!");
8 | }
9 | }
10 |
11 | static class MyRun implements Runnable {
12 | @Override
13 | public void run() {
14 | System.out.println("Hello MyRun!");
15 | }
16 | }
17 |
18 | public static void main(String[] args) {
19 | new MyThread().start();
20 | new Thread(new MyRun()).start();
21 | new Thread(()->{
22 | System.out.println("Hello Lambda!");
23 | }).start();
24 | }
25 |
26 | }
27 |
28 | //请你告诉我启动线程的三种方式 1:Thread 2: Runnable 3:Executors.newCachedThrad
29 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_000/T03_Sleep_Yield_Join.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_000;
2 |
3 | public class T03_Sleep_Yield_Join {
4 | public static void main(String[] args) {
5 | // testSleep();
6 | // testYield();
7 | testJoin();
8 | }
9 |
10 | static void testSleep() {
11 | new Thread(()->{
12 | for(int i=0; i<100; i++) {
13 | System.out.println("A" + i);
14 | try {
15 | Thread.sleep(500);
16 | //TimeUnit.Milliseconds.sleep(500)
17 | } catch (InterruptedException e) {
18 | e.printStackTrace();
19 | }
20 | }
21 | }).start();
22 | }
23 |
24 | static void testYield() {
25 | new Thread(()->{
26 | for(int i=0; i<100; i++) {
27 | System.out.println("A" + i);
28 | if(i%10 == 0) Thread.yield();
29 |
30 |
31 | }
32 | }).start();
33 |
34 | new Thread(()->{
35 | for(int i=0; i<100; i++) {
36 | System.out.println("------------B" + i);
37 | if(i%10 == 0) Thread.yield();
38 | }
39 | }).start();
40 | }
41 |
42 | static void testJoin() {
43 | Thread t1 = new Thread(()->{
44 | for(int i=0; i<100; i++) {
45 | System.out.println("A" + i);
46 | try {
47 | Thread.sleep(500);
48 | //TimeUnit.Milliseconds.sleep(500)
49 | } catch (InterruptedException e) {
50 | e.printStackTrace();
51 | }
52 | }
53 | });
54 |
55 | Thread t2 = new Thread(()->{
56 |
57 | try {
58 | t1.join();
59 | } catch (InterruptedException e) {
60 | e.printStackTrace();
61 | }
62 |
63 | for(int i=0; i<100; i++) {
64 | System.out.println("A" + i);
65 | try {
66 | Thread.sleep(500);
67 | //TimeUnit.Milliseconds.sleep(500)
68 | } catch (InterruptedException e) {
69 | e.printStackTrace();
70 | }
71 | }
72 | });
73 |
74 | t1.start();
75 | t2.start();
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_000/T04_ThreadState.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_000;
2 |
3 | public class T04_ThreadState {
4 |
5 | static class MyThread extends Thread {
6 | @Override
7 | public void run() {
8 | System.out.println(this.getState());
9 |
10 | for(int i=0; i<10; i++) {
11 | try {
12 | Thread.sleep(500);
13 | } catch (InterruptedException e) {
14 | e.printStackTrace();
15 | }
16 |
17 | System.out.println(i);
18 | }
19 | }
20 | }
21 |
22 | public static void main(String[] args) {
23 | Thread t = new MyThread();
24 |
25 | System.out.println(t.getState());
26 |
27 | t.start();
28 |
29 | try {
30 | t.join();
31 | } catch (InterruptedException e) {
32 | e.printStackTrace();
33 | }
34 |
35 | System.out.println(t.getState());
36 |
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_001/T.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_001/T.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_002/T.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_002/T.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_003/T.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_003/T.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_003/T1.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_003/T1.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_004/T.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_004/T.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_005/T.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_005/T.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_006/T.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_006/T.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_007/T.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_007/T.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_008/Account.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_008/Account.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_009/T.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_009/T.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_010/T.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_010/T.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_011/T.java:
--------------------------------------------------------------------------------
1 | /**
2 | * 程序在执行过程中,如果出现异常,默认情况锁会被释放
3 | * 所以,在并发处理的过程中,有异常要多加小心,不然可能会发生不一致的情况。
4 | * 比如,在一个web app处理过程中,多个servlet线程共同访问同一个资源,这时如果异常处理不合适,
5 | * 在第一个线程中抛出异常,其他线程就会进入同步代码区,有可能会访问到异常产生时的数据。
6 | * 因此要非常小心的处理同步业务逻辑中的异常
7 | * @author mashibing
8 | */
9 | package com.mashibing.juc.c_011;
10 |
11 | import java.util.concurrent.TimeUnit;
12 |
13 | public class T {
14 | int count = 0;
15 | synchronized void m() {
16 | System.out.println(Thread.currentThread().getName() + " start");
17 | while(true) {
18 | count ++;
19 | System.out.println(Thread.currentThread().getName() + " count = " + count);
20 | try {
21 | TimeUnit.SECONDS.sleep(1);
22 |
23 | } catch (InterruptedException e) {
24 | e.printStackTrace();
25 | }
26 |
27 | if(count == 5) {
28 | int i = 1/0; //此处抛出异常,锁将被释放,要想不被释放,可以在这里进行catch,然后让循环继续
29 | System.out.println(i);
30 | }
31 | }
32 | }
33 |
34 | public static void main(String[] args) {
35 | T t = new T();
36 | Runnable r = new Runnable() {
37 |
38 | @Override
39 | public void run() {
40 | t.m();
41 | }
42 |
43 | };
44 | new Thread(r, "t1").start();
45 |
46 | try {
47 | TimeUnit.SECONDS.sleep(3);
48 | } catch (InterruptedException e) {
49 | e.printStackTrace();
50 | }
51 |
52 | new Thread(r, "t2").start();
53 | }
54 |
55 | }
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_011_01/readme:
--------------------------------------------------------------------------------
1 | synchronized的底层实现
2 | JDK早期的 重量级 - OS
3 | 后来的改进
4 | 锁升级的概念:
5 | 我就是厕所所长 (一 二)
6 |
7 | sync (Object)
8 | markword 记录这个线程ID (偏向锁)
9 | 如果线程争用:升级为 自旋锁
10 | 10次以后,
11 | 升级为重量级锁 - OS
12 |
13 | 执行时间短(加锁代码),线程数少,用自旋
14 | 执行时间长,线程数多,用系统锁
15 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_012_Volatile/T01_HelloVolatile.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_012_Volatile/T01_HelloVolatile.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_012_Volatile/T02_VolatileReference1.java:
--------------------------------------------------------------------------------
1 | /**
2 | * volatile 引用类型(包括数组)只能保证引用本身的可见性,不能保证内部字段的可见性
3 | */
4 | package com.mashibing.juc.c_012_Volatile;
5 |
6 | import java.util.concurrent.TimeUnit;
7 |
8 | public class T02_VolatileReference1 {
9 |
10 | boolean running = true;
11 |
12 | volatile static T02_VolatileReference1 T = new T02_VolatileReference1();
13 |
14 |
15 | void m() {
16 | System.out.println("m start");
17 | while(running) {
18 | /*
19 | try {
20 | TimeUnit.MILLISECONDS.sleep(10);
21 | } catch (InterruptedException e) {
22 | e.printStackTrace();
23 | }*/
24 | }
25 | System.out.println("m end!");
26 | }
27 |
28 | public static void main(String[] args) {
29 | new Thread(T::m, "t1").start();
30 |
31 | //lambda表达式 new Thread(new Runnable( run() {m()}
32 |
33 | try {
34 | TimeUnit.SECONDS.sleep(1);
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }
38 |
39 | T.running = false;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_012_Volatile/T03________VolatileReference2.java:
--------------------------------------------------------------------------------
1 | /**
2 | * volatile 引用类型(包括数组)只能保证引用本身的可见性,不能保证内部字段的可见性
3 | */
4 | package com.mashibing.juc.c_012_Volatile;
5 |
6 | public class T03________VolatileReference2 {
7 |
8 | private static class Data {
9 | int a, b;
10 |
11 | public Data(int a, int b) {
12 | this.a = a;
13 | this.b = b;
14 | }
15 | }
16 |
17 | volatile static Data data;
18 |
19 | public static void main(String[] args) {
20 | Thread writer = new Thread(()->{
21 | for (int i = 0; i < 10000; i++) {
22 | data = new Data(i, i);
23 | }
24 | });
25 |
26 | Thread reader = new Thread(()->{
27 | while (data == null) {}
28 | int x = data.a;
29 | int y = data.b;
30 | if(x != y) {
31 | System.out.printf("a = %s, b=%s%n", x, y);
32 | }
33 | });
34 |
35 | reader.start();
36 | writer.start();
37 |
38 | try {
39 | reader.join();
40 | writer.join();
41 | } catch (InterruptedException e) {
42 | e.printStackTrace();
43 | }
44 |
45 | System.out.println("end");
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_012_Volatile/T04_VolatileNotSync.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_012_Volatile/T04_VolatileNotSync.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_012_Volatile/T05_VolatileVsSync.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_012_Volatile/T05_VolatileVsSync.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_016_LockOptimization/FineCoarseLock.java:
--------------------------------------------------------------------------------
1 | /**
2 | * synchronized优化
3 | * 同步代码块中的语句越少越好
4 | * 比较m1和m2
5 | * @author mashibing
6 | */
7 | package com.mashibing.juc.c_016_LockOptimization;
8 |
9 | import java.util.concurrent.TimeUnit;
10 |
11 |
12 | public class FineCoarseLock {
13 |
14 | int count = 0;
15 |
16 | synchronized void m1() {
17 | //do sth need not sync
18 | try {
19 | TimeUnit.SECONDS.sleep(2);
20 | } catch (InterruptedException e) {
21 | e.printStackTrace();
22 | }
23 | //业务逻辑中只有下面这句需要sync,这时不应该给整个方法上锁
24 | count ++;
25 |
26 | //do sth need not sync
27 | try {
28 | TimeUnit.SECONDS.sleep(2);
29 | } catch (InterruptedException e) {
30 | e.printStackTrace();
31 | }
32 | }
33 |
34 | void m2() {
35 | //do sth need not sync
36 | try {
37 | TimeUnit.SECONDS.sleep(2);
38 | } catch (InterruptedException e) {
39 | e.printStackTrace();
40 | }
41 | //业务逻辑中只有下面这句需要sync,这时不应该给整个方法上锁
42 | //采用细粒度的锁,可以使线程争用时间变短,从而提高效率
43 | synchronized(this) {
44 | count ++;
45 | }
46 | //do sth need not sync
47 | try {
48 | TimeUnit.SECONDS.sleep(2);
49 | } catch (InterruptedException e) {
50 | e.printStackTrace();
51 | }
52 | }
53 |
54 |
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_017_MoreAboutSync/DoNotLockString.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_017_MoreAboutSync/DoNotLockString.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_017_MoreAboutSync/SyncSameObject.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_017_MoreAboutSync/SyncSameObject.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_018_00_AtomicXXX/T01_AtomicInteger.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_018_00_AtomicXXX/T01_AtomicInteger.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_018_00_AtomicXXX/T02_AtomicVsSyncVsLongAdder.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_018_00_AtomicXXX;
2 |
3 | import java.util.concurrent.TimeUnit;
4 | import java.util.concurrent.atomic.AtomicLong;
5 | import java.util.concurrent.atomic.LongAdder;
6 |
7 | public class T02_AtomicVsSyncVsLongAdder {
8 | static long count2 = 0L;
9 | static AtomicLong count1 = new AtomicLong(0L);
10 | static LongAdder count3 = new LongAdder();
11 |
12 | public static void main(String[] args) throws Exception {
13 | Thread[] threads = new Thread[1000];
14 |
15 | for(int i=0; i {
18 | for(int k=0; k<100000; k++) count1.incrementAndGet();
19 | });
20 | }
21 |
22 | long start = System.currentTimeMillis();
23 |
24 | for(Thread t : threads ) t.start();
25 |
26 | for (Thread t : threads) t.join();
27 |
28 | long end = System.currentTimeMillis();
29 |
30 | //TimeUnit.SECONDS.sleep(10);
31 |
32 | System.out.println("Atomic: " + count1.get() + " time " + (end-start));
33 | //-----------------------------------------------------------
34 | Object lock = new Object();
35 |
36 | for(int i=0; i {
66 | for(int k=0; k<100000; k++) count3.increment();
67 | });
68 | }
69 |
70 | start = System.currentTimeMillis();
71 |
72 | for(Thread t : threads ) t.start();
73 |
74 | for (Thread t : threads) t.join();
75 |
76 | end = System.currentTimeMillis();
77 |
78 | //TimeUnit.SECONDS.sleep(10);
79 |
80 | System.out.println("LongAdder: " + count1.longValue() + " time " + (end-start));
81 |
82 | }
83 |
84 | static void microSleep(int m) {
85 | try {
86 | TimeUnit.MICROSECONDS.sleep(m);
87 | } catch (InterruptedException e) {
88 | e.printStackTrace();
89 | }
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_018_00_AtomicXXX/T03________SyncVsLongAdder.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_018_00_AtomicXXX;
2 |
3 | import java.util.concurrent.TimeUnit;
4 | import java.util.concurrent.atomic.LongAdder;
5 |
6 | public class T03________SyncVsLongAdder {
7 | static long count2 = 0L;
8 | static LongAdder count = new LongAdder();
9 |
10 | public static void main(String[] args) throws Exception {
11 | Thread[] threads = new Thread[500];
12 |
13 | for(int i=0; i {
16 | for(int k=0; k<100000; k++) count.increment();
17 | });
18 | }
19 |
20 | long start = System.currentTimeMillis();
21 |
22 | for(Thread t : threads ) t.start();
23 |
24 | for (Thread t : threads) t.join();
25 |
26 | long end = System.currentTimeMillis();
27 |
28 | //TimeUnit.SECONDS.sleep(10);
29 |
30 | System.out.println("LongAdder: " + count.longValue() + " time " + (end-start));
31 | //-----------------------------------------------------------
32 | Object lock = new Object();
33 |
34 | for(int i=0; i{
17 | int result = 0;
18 | for(int j=0; j<10000; j++) result += j;
19 | latch.countDown();
20 | });
21 | }
22 |
23 | for (int i = 0; i < threads.length; i++) {
24 | threads[i].start();
25 | }
26 |
27 | try {
28 | latch.await();
29 | } catch (InterruptedException e) {
30 | e.printStackTrace();
31 | }
32 |
33 | System.out.println("end latch");
34 | }
35 |
36 | private static void usingJoin() {
37 | Thread[] threads = new Thread[100];
38 |
39 | for(int i=0; i{
41 | int result = 0;
42 | for(int j=0; j<10000; j++) result += j;
43 | });
44 | }
45 |
46 | for (int i = 0; i < threads.length; i++) {
47 | threads[i].start();
48 | }
49 |
50 | for (int i = 0; i < threads.length; i++) {
51 | try {
52 | threads[i].join();
53 | } catch (InterruptedException e) {
54 | e.printStackTrace();
55 | }
56 | }
57 |
58 | System.out.println("end join");
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020/T07_TestCyclicBarrier.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020/T07_TestCyclicBarrier.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020/T08_TestPhaser.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020/T08_TestPhaser.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020/T09_TestPhaser2.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020/T09_TestPhaser2.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020/T10_TestReadWriteLock.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_020;
2 |
3 | import java.util.Random;
4 | import java.util.concurrent.atomic.LongAdder;
5 | import java.util.concurrent.locks.Lock;
6 | import java.util.concurrent.locks.ReadWriteLock;
7 | import java.util.concurrent.locks.ReentrantLock;
8 | import java.util.concurrent.locks.ReentrantReadWriteLock;
9 |
10 | public class T10_TestReadWriteLock {
11 | static Lock lock = new ReentrantLock();
12 | private static int value;
13 |
14 | static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
15 | static Lock readLock = readWriteLock.readLock();
16 | static Lock writeLock = readWriteLock.writeLock();
17 |
18 | public static void read(Lock lock) {
19 | try {
20 | lock.lock();
21 | Thread.sleep(1000);
22 | System.out.println("read over!");
23 | //模拟读取操作
24 | } catch (InterruptedException e) {
25 | e.printStackTrace();
26 | } finally {
27 | lock.unlock();
28 | }
29 | }
30 |
31 | public static void write(Lock lock, int v) {
32 | try {
33 | lock.lock();
34 | Thread.sleep(1000);
35 | value = v;
36 | System.out.println("write over!");
37 | //模拟写操作
38 | } catch (InterruptedException e) {
39 | e.printStackTrace();
40 | } finally {
41 | lock.unlock();
42 | }
43 | }
44 |
45 |
46 |
47 |
48 |
49 | public static void main(String[] args) {
50 | //Runnable readR = ()-> read(lock);
51 | Runnable readR = ()-> read(readLock);
52 |
53 | //Runnable writeR = ()->write(lock, new Random().nextInt());
54 | Runnable writeR = ()->write(writeLock, new Random().nextInt());
55 |
56 | for(int i=0; i<18; i++) new Thread(readR).start();
57 | for(int i=0; i<2; i++) new Thread(writeR).start();
58 |
59 |
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020/T11_TestSemaphore.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_020;
2 |
3 | import java.util.concurrent.Semaphore;
4 |
5 | public class T11_TestSemaphore {
6 | public static void main(String[] args) {
7 | //Semaphore s = new Semaphore(2);
8 | Semaphore s = new Semaphore(2, true);
9 | //允许一个线程同时执行
10 | //Semaphore s = new Semaphore(1);
11 |
12 | new Thread(()->{
13 | try {
14 | s.acquire();
15 |
16 | System.out.println("T1 running...");
17 | Thread.sleep(200);
18 | System.out.println("T1 running...");
19 |
20 | } catch (InterruptedException e) {
21 | e.printStackTrace();
22 | } finally {
23 | s.release();
24 | }
25 | }).start();
26 |
27 | new Thread(()->{
28 | try {
29 | s.acquire();
30 |
31 | System.out.println("T2 running...");
32 | Thread.sleep(200);
33 | System.out.println("T2 running...");
34 |
35 | s.release();
36 | } catch (InterruptedException e) {
37 | e.printStackTrace();
38 | }
39 | }).start();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020/T12_TestExchanger.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_020;
2 |
3 | import java.util.concurrent.Exchanger;
4 |
5 | public class T12_TestExchanger {
6 |
7 | static Exchanger exchanger = new Exchanger<>();
8 |
9 | public static void main(String[] args) {
10 | new Thread(()->{
11 | String s = "T1";
12 | try {
13 | s = exchanger.exchange(s);
14 | } catch (InterruptedException e) {
15 | e.printStackTrace();
16 | }
17 | System.out.println(Thread.currentThread().getName() + " " + s);
18 |
19 | }, "t1").start();
20 |
21 |
22 | new Thread(()->{
23 | String s = "T2";
24 | try {
25 | s = exchanger.exchange(s);
26 | } catch (InterruptedException e) {
27 | e.printStackTrace();
28 | }
29 | System.out.println(Thread.currentThread().getName() + " " + s);
30 |
31 | }, "t2").start();
32 |
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020/T13_TestLockSupport.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_020;
2 |
3 | import java.util.concurrent.TimeUnit;
4 | import java.util.concurrent.locks.LockSupport;
5 |
6 | public class T13_TestLockSupport {
7 | public static void main(String[] args) {
8 | Thread t = new Thread(()->{
9 | for (int i = 0; i < 10; i++) {
10 | System.out.println(i);
11 | if(i == 5) {
12 | LockSupport.park();
13 | }
14 | try {
15 | TimeUnit.SECONDS.sleep(1);
16 | } catch (InterruptedException e) {
17 | e.printStackTrace();
18 | }
19 | }
20 | });
21 |
22 | t.start();
23 |
24 | LockSupport.unpark(t);
25 |
26 | /*try {
27 | TimeUnit.SECONDS.sleep(8);
28 | } catch (InterruptedException e) {
29 | e.printStackTrace();
30 | }
31 | System.out.println("after 8 senconds!");
32 |
33 | LockSupport.unpark(t);*/
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020_01_Interview/T01_WithoutVolatile.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020_01_Interview/T01_WithoutVolatile.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020_01_Interview/T02_WithVolatile.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020_01_Interview/T02_WithVolatile.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020_01_Interview/T03_NotifyHoldingLock.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020_01_Interview/T03_NotifyHoldingLock.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020_01_Interview/T04_NotifyFreeLock.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020_01_Interview/T04_NotifyFreeLock.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020_01_Interview/T05_CountDownLatch.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020_01_Interview/T05_CountDownLatch.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020_01_Interview/T06_LockSupport.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020_01_Interview/T06_LockSupport.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020_01_Interview/T07_LockSupport_WithoutSleep.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020_01_Interview/T07_LockSupport_WithoutSleep.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_020_01_Interview/T08_Semaphore.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_020_01_Interview/T08_Semaphore.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_021_01_interview/MyContainer1.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjmashibing/JUC/5bd8698269f3880a0734057465efdce86595ddb8/src/main/java/com/mashibing/juc/c_021_01_interview/MyContainer1.java
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_021_01_interview/MyContainer2.java:
--------------------------------------------------------------------------------
1 | /**
2 | * 面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法,
3 | * 能够支持2个生产者线程以及10个消费者线程的阻塞调用
4 | *
5 | * 使用wait和notify/notifyAll来实现
6 | *
7 | * 使用Lock和Condition来实现
8 | * 对比两种方式,Condition的方式可以更加精确的指定哪些线程被唤醒
9 | *
10 | * @author mashibing
11 | */
12 | package com.mashibing.juc.c_021_01_interview;
13 |
14 | import java.util.LinkedList;
15 | import java.util.concurrent.TimeUnit;
16 | import java.util.concurrent.locks.Condition;
17 | import java.util.concurrent.locks.Lock;
18 | import java.util.concurrent.locks.ReentrantLock;
19 |
20 | public class MyContainer2 {
21 | final private LinkedList lists = new LinkedList<>();
22 | final private int MAX = 10; //最多10个元素
23 | private int count = 0;
24 |
25 | private Lock lock = new ReentrantLock();
26 | private Condition producer = lock.newCondition();
27 | private Condition consumer = lock.newCondition();
28 |
29 | public void put(T t) {
30 | try {
31 | lock.lock();
32 | while(lists.size() == MAX) { //想想为什么用while而不是用if?
33 | producer.await();
34 | }
35 |
36 | lists.add(t);
37 | ++count;
38 | consumer.signalAll(); //通知消费者线程进行消费
39 | } catch (InterruptedException e) {
40 | e.printStackTrace();
41 | } finally {
42 | lock.unlock();
43 | }
44 | }
45 |
46 | public T get() {
47 | T t = null;
48 | try {
49 | lock.lock();
50 | while(lists.size() == 0) {
51 | consumer.await();
52 | }
53 | t = lists.removeFirst();
54 | count --;
55 | producer.signalAll(); //通知生产者进行生产
56 | } catch (InterruptedException e) {
57 | e.printStackTrace();
58 | } finally {
59 | lock.unlock();
60 | }
61 | return t;
62 | }
63 |
64 | public static void main(String[] args) {
65 | MyContainer2 c = new MyContainer2<>();
66 | //启动消费者线程
67 | for(int i=0; i<10; i++) {
68 | new Thread(()->{
69 | for(int j=0; j<5; j++) System.out.println(c.get());
70 | }, "c" + i).start();
71 | }
72 |
73 | try {
74 | TimeUnit.SECONDS.sleep(2);
75 | } catch (InterruptedException e) {
76 | e.printStackTrace();
77 | }
78 |
79 | //启动生产者线程
80 | for(int i=0; i<2; i++) {
81 | new Thread(()->{
82 | for(int j=0; j<25; j++) c.put(Thread.currentThread().getName() + " " + j);
83 | }, "p" + i).start();
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_021_02_AQS/MLock.java:
--------------------------------------------------------------------------------
1 | /**
2 | * 通过AQS实现自定义锁,目前仅实现了lock和unlock
3 | * @author 马士兵
4 | */
5 | package com.mashibing.juc.c_021_02_AQS;
6 |
7 | import java.util.concurrent.TimeUnit;
8 | import java.util.concurrent.locks.Condition;
9 | import java.util.concurrent.locks.Lock;
10 |
11 | public class MLock implements Lock {
12 |
13 | private Sync sync = new Sync();
14 |
15 | @Override
16 | public void lock() {
17 | sync.acquire(1);
18 | }
19 |
20 | @Override
21 | public void unlock() {
22 | sync.release(1);
23 | }
24 |
25 | @Override
26 | public void lockInterruptibly() throws InterruptedException {
27 |
28 | }
29 |
30 | @Override
31 | public boolean tryLock() {
32 | return false;
33 | }
34 |
35 | @Override
36 | public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
37 | return false;
38 | }
39 |
40 | @Override
41 | public Condition newCondition() {
42 | return null;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_021_02_AQS/Main.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_021_02_AQS;
2 |
3 | import java.util.concurrent.locks.Lock;
4 |
5 | public class Main {
6 | public static int m = 0;
7 | public static Lock lock = new MLock();
8 |
9 | public static void main(String[] args) throws Exception {
10 | Thread[] threads = new Thread[100];
11 |
12 | for(int i=0; i{
14 | try {
15 | lock.lock();
16 | for (int j = 0; j < 100; j++) m++;
17 | } finally {
18 | lock.unlock();
19 | }
20 | });
21 | }
22 |
23 | for(Thread t : threads) t.start();
24 |
25 | for (Thread t : threads) t.join();
26 |
27 | System.out.println(m);
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_021_02_AQS/Sync.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_021_02_AQS;
2 |
3 | import java.util.concurrent.locks.AbstractQueuedSynchronizer;
4 |
5 | public class Sync extends AbstractQueuedSynchronizer {
6 | @Override
7 | protected boolean tryAcquire(int arg) {
8 | if(compareAndSetState(0, 1)) {
9 | setExclusiveOwnerThread(Thread.currentThread());
10 | return true;
11 | }
12 | return false;
13 | }
14 |
15 | @Override
16 | protected boolean tryRelease(int arg) {
17 | setExclusiveOwnerThread(null);
18 | setState(0);
19 | return true;
20 | }
21 |
22 | @Override
23 | protected boolean isHeldExclusively() {
24 | return getState() == 1;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_021_02_AQS/TestReentrantLock.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_021_02_AQS;
2 |
3 | import java.util.concurrent.locks.ReentrantLock;
4 |
5 | public class TestReentrantLock {
6 |
7 | private static volatile int i = 0;
8 |
9 | public static void main(String[] args) {
10 | ReentrantLock lock = new ReentrantLock();
11 | lock.lock();
12 | //synchronized (TestReentrantLock.class) {
13 | i++;
14 | //}
15 |
16 | lock.unlock();
17 |
18 | //synchronized 程序员的丽春院 JUC
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_021_03_VarHandle/T01_HelloVarHandle.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_021_03_VarHandle;
2 |
3 | import java.lang.invoke.MethodHandles;
4 | import java.lang.invoke.VarHandle;
5 |
6 | public class T01_HelloVarHandle {
7 |
8 | int x = 8;
9 |
10 | private static VarHandle handle;
11 |
12 | static {
13 | try {
14 | handle = MethodHandles.lookup().findVarHandle(T01_HelloVarHandle.class, "x", int.class);
15 | } catch (NoSuchFieldException e) {
16 | e.printStackTrace();
17 | } catch (IllegalAccessException e) {
18 | e.printStackTrace();
19 | }
20 | }
21 |
22 | public static void main(String[] args) {
23 | T01_HelloVarHandle t = new T01_HelloVarHandle();
24 |
25 | //plain read / write
26 | System.out.println((int)handle.get(t));
27 | handle.set(t,9);
28 | System.out.println(t.x);
29 |
30 | handle.compareAndSet(t, 9, 10);
31 | System.out.println(t.x);
32 |
33 | handle.getAndAdd(t, 10);
34 | System.out.println(t.x);
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_022_RefTypeAndThreadLocal/M.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_022_RefTypeAndThreadLocal;
2 |
3 | public class M {
4 | @Override
5 | protected void finalize() throws Throwable {
6 | System.out.println("finalize");
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_022_RefTypeAndThreadLocal/T01_NormalReference.java:
--------------------------------------------------------------------------------
1 | package com.mashibing.juc.c_022_RefTypeAndThreadLocal;
2 |
3 | import java.io.IOException;
4 |
5 | public class T01_NormalReference {
6 | public static void main(String[] args) throws IOException {
7 | M m = new M();
8 | m = null;
9 | System.gc(); //DisableExplicitGC
10 |
11 | System.in.read();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_022_RefTypeAndThreadLocal/T02_SoftReference.java:
--------------------------------------------------------------------------------
1 | /**
2 | * 软引用
3 | * 软引用是用来描述一些还有用但并非必须的对象。
4 | * 对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围进行第二次回收。
5 | * 如果这次回收还没有足够的内存,才会抛出内存溢出异常。
6 | * -Xmx20M
7 | */
8 | package com.mashibing.juc.c_022_RefTypeAndThreadLocal;
9 |
10 | import java.lang.ref.SoftReference;
11 |
12 | public class T02_SoftReference {
13 | public static void main(String[] args) {
14 | SoftReference m = new SoftReference<>(new byte[1024*1024*10]);
15 | //m = null;
16 | System.out.println(m.get());
17 | System.gc();
18 | try {
19 | Thread.sleep(500);
20 | } catch (InterruptedException e) {
21 | e.printStackTrace();
22 | }
23 | System.out.println(m.get());
24 |
25 | //再分配一个数组,heap将装不下,这时候系统会垃圾回收,先回收一次,如果不够,会把软引用干掉
26 | byte[] b = new byte[1024*1024*15];
27 | System.out.println(m.get());
28 | }
29 | }
30 |
31 | //软引用非常适合缓存使用
32 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_022_RefTypeAndThreadLocal/T03_WeakReference.java:
--------------------------------------------------------------------------------
1 | /**
2 | * 弱引用遭到gc就会回收
3 | *
4 | */
5 | package com.mashibing.juc.c_022_RefTypeAndThreadLocal;
6 |
7 | import java.lang.ref.WeakReference;
8 |
9 | public class T03_WeakReference {
10 | public static void main(String[] args) {
11 | WeakReference m = new WeakReference<>(new M());
12 |
13 | System.out.println(m.get());
14 | System.gc();
15 | System.out.println(m.get());
16 |
17 |
18 | ThreadLocal tl = new ThreadLocal<>();
19 | tl.set(new M());
20 | tl.remove();
21 |
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/src/main/java/com/mashibing/juc/c_022_RefTypeAndThreadLocal/T04_PhantomReference.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | *
4 | * 一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,
5 | * 也无法通过虚引用来获取一个对象的实例。
6 | * 为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
7 | * 虚引用和弱引用对关联对象的回收都不会产生影响,如果只有虚引用活着弱引用关联着对象,
8 | * 那么这个对象就会被回收。它们的不同之处在于弱引用的get方法,虚引用的get方法始终返回null,
9 | * 弱引用可以使用ReferenceQueue,虚引用必须配合ReferenceQueue使用。
10 | *
11 | * jdk中直接内存的回收就用到虚引用,由于jvm自动内存管理的范围是堆内存,
12 | * 而直接内存是在堆内存之外(其实是内存映射文件,自行去理解虚拟内存空间的相关概念),
13 | * 所以直接内存的分配和回收都是有Unsafe类去操作,java在申请一块直接内存之后,
14 | * 会在堆内存分配一个对象保存这个堆外内存的引用,
15 | * 这个对象被垃圾收集器管理,一旦这个对象被回收,
16 | * 相应的用户线程会收到通知并对直接内存进行清理工作。
17 | *
18 | * 事实上,虚引用有一个很重要的用途就是用来做堆外内存的释放,
19 | * DirectByteBuffer就是通过虚引用来实现堆外内存的释放的。
20 | *
21 | */
22 |
23 |
24 | package com.mashibing.juc.c_022_RefTypeAndThreadLocal;
25 |
26 | import java.lang.ref.PhantomReference;
27 | import java.lang.ref.Reference;
28 | import java.lang.ref.ReferenceQueue;
29 | import java.util.LinkedList;
30 | import java.util.List;
31 |
32 | public class T04_PhantomReference {
33 | private static final List