java.util.concurrentã«ã¯ãæ©èœã«å¿ããŠã°ã«ãŒãã«åé¡ã§ããå€ãã®ç°ãªãã¯ã©ã¹ããããŸããConcurrentCollectionsãExecutorsãAtomicsãªã©ã§ãã ãããã®ã°ã«ãŒãã®1ã€ã¯ã·ã³ã¯ããã€ã¶ãŒã§ãã
ã·ã³ã¯ããã€ã¶ãŒã¯ããããŒãåæããããã®è£å©ãŠãŒãã£ãªãã£ã§ããããã«ãããéçºè ã¯ããããŒã®åäœã調æŽããã³/ãŸãã¯å¶éããåºæ¬çãªèšèªããªããã£ãïŒã¢ãã¿ãŒïŒãããé«ãæœè±¡åºŠãæäŸã§ããŸãã
ã»ããã©
ã»ããã©ã·ã³ã¯ããã€ã¶ã¯ã ã»ããã©åæãã¿ãŒã³ãå®è£ ããŸãã å ±æãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãå¶éããå¿ èŠãããå Žåãã»ãšãã©ã®å Žåãã»ããã©ãå¿ èŠã§ãã ãã®ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ïŒ
Semaphore(int permits)
ãŸãã¯
Semaphore(int permits, boolean fair)
ïŒã¯ãã»ããã©ãæå®ããããªãœãŒã¹ãåæã«äœ¿çšã§ããã¹ã¬ããã®æ°ãæž¡ãå¿ èŠããããŸãã
ã¢ã¯ã»ã¹ã¯ã«ãŠã³ã¿ã«ãã£ãŠå¶åŸ¡ãããŸããæåã¯ãã«ãŠã³ã¿å€ã¯
int permits
ã§ããã¹ããªãŒã ãç¹å®ã®ã³ãŒããããã¯ã«å ¥ããšãã«ãŠã³ã¿å€ã¯1æžå°ããã¹ããªãŒã ããããé¢ãããšå¢å ããŸãã ã«ãŠã³ã¿ãŒå€ããŒãã®å Žåã誰ãããããã¯ãé¢ãããŸã§çŸåšã®ãããŒããããã¯ãããŸãïŒ
permits = 1
ç掻ã®äŸãšããŠã蚺çæã®ãªãã£ã¹ã«ãã¥ãŒãæã¡èŸŒãããšãã§ããŸãïŒæ£è ããªãã£ã¹ãé¢ãããšãã©ã³ããç¹æ» ãã次ã®æ£è ãå ¥å®€ããŸãïŒ ïŒ
ã»ããã©ã®å ¬åŒããã¥ã¡ã³ãã
ã»ããã©ã®äŸ
次ã®äŸãèããŠã¿ãŸãããã äžåºŠã«5å°ãŸã§ããé§è»ã§ããªãé§è»å ŽããããŸãã é§è»å Žãå®å
šã«æºè»ã®å Žåãæ°ããå°çããè»ã¯ãå°ãªããšã1åžã空ããŸã§åŸ
ããªããã°ãªããŸããã ãã®åŸã圌ã¯é§è»ããããšãã§ããŸãã
ã»ããã©ã¯ãã®åé¡ã解決ããã®ã«æé©ã§ãïŒé§è»ã¹ããŒã¹ããªãå ŽåïŒã«ãŠã³ã¿ãŒã¯0ïŒãè»ïŒã¹ããªãŒã ïŒãé§è»ïŒç¹å®ã®ã³ãŒããããã¯ã«ç§»åããå ±æãªãœãŒã¹ã䜿çšïŒããããšãèš±å¯ããŸãããã»ããã©ã¯ã©ã¹ã¯è€æ°ã®ãã£ããã£ãšè§£æŸããµããŒãããããšã«æ³šæããŠãã ããäžåºŠã«èš±å¯ãããŸããããã®ã¿ã¹ã¯ã¯å¿ èŠãããŸããã
import java.util.concurrent.Semaphore; public class Parking { // - true, - false private static final boolean[] PARKING_PLACES = new boolean[5]; // "", //aquire() private static final Semaphore SEMAPHORE = new Semaphore(5, true); public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 7; i++) { new Thread(new Car(i)).start(); Thread.sleep(400); } } public static class Car implements Runnable { private int carNumber; public Car(int carNumber) { this.carNumber = carNumber; } @Override public void run() { System.out.printf(" â%d .\n", carNumber); try { //acquire() , // , , // SEMAPHORE.acquire(); int parkingNumber = -1; // synchronized (PARKING_PLACES){ for (int i = 0; i < 5; i++) if (!PARKING_PLACES[i]) { // PARKING_PLACES[i] = true; // parkingNumber = i; // , System.out.printf(" â%d %d.\n", carNumber, i); break; } } Thread.sleep(5000); // , synchronized (PARKING_PLACES) { PARKING_PLACES[parkingNumber] = false;// } //release(), , SEMAPHORE.release(); System.out.printf(" â%d .\n", carNumber); } catch (InterruptedException e) { } } } }
ããã°ã©ã ã®çµæ
1å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
1å·è»ã¯0ã«é§è»ãããŸããã
2å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
2å·è»ã¯1çªã«é§è»ãããŸããã
3å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
3å·è»ã¯2çªã«é§è»ãããŸããã
4å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
4å·è»ã¯3çªã«é§è»ãããŸããã
5å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
5å·è»ã¯4çªã«é§è»ãããŸããã
6å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
7å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
1å·è»ãé§è»å ŽãåºãŸããã
è»çªå·6ã¯0ã«é§è»ãããŸããã
2å·è»ãé§è»å ŽãåºãŸããã
7çªã®è»ãæå®ã®å Žæã«é§è»ããŠããŸãã
3å·è»ãé§è»å ŽãåºãŸããã
4å·è»ãé§è»å ŽãåºãŸããã
5å·è»ãé§è»å ŽãåºãŸããã
6å·è»ãé§è»å ŽãåºãŸããã
7å·è»ãé§è»å ŽãåºãŸããã
1å·è»ã¯0ã«é§è»ãããŸããã
2å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
2å·è»ã¯1çªã«é§è»ãããŸããã
3å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
3å·è»ã¯2çªã«é§è»ãããŸããã
4å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
4å·è»ã¯3çªã«é§è»ãããŸããã
5å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
5å·è»ã¯4çªã«é§è»ãããŸããã
6å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
7å·è»ã¯é§è»å ŽãŸã§é転ããŸããã
1å·è»ãé§è»å ŽãåºãŸããã
è»çªå·6ã¯0ã«é§è»ãããŸããã
2å·è»ãé§è»å ŽãåºãŸããã
7çªã®è»ãæå®ã®å Žæã«é§è»ããŠããŸãã
3å·è»ãé§è»å ŽãåºãŸããã
4å·è»ãé§è»å ŽãåºãŸããã
5å·è»ãé§è»å ŽãåºãŸããã
6å·è»ãé§è»å ŽãåºãŸããã
7å·è»ãé§è»å ŽãåºãŸããã
ã»ããã©ã¯ãã®åé¡ã解決ããã®ã«æé©ã§ãïŒé§è»ã¹ããŒã¹ããªãå ŽåïŒã«ãŠã³ã¿ãŒã¯0ïŒãè»ïŒã¹ããªãŒã ïŒãé§è»ïŒç¹å®ã®ã³ãŒããããã¯ã«ç§»åããå ±æãªãœãŒã¹ã䜿çšïŒããããšãèš±å¯ããŸãããã»ããã©ã¯ã©ã¹ã¯è€æ°ã®ãã£ããã£ãšè§£æŸããµããŒãããããšã«æ³šæããŠãã ããäžåºŠã«èš±å¯ãããŸããããã®ã¿ã¹ã¯ã¯å¿ èŠãããŸããã
CountDownLatch
CountDownLatchïŒã«ãŠã³ãããŠã³ä»ãããã¯ïŒã䜿çšãããšãã³ãŒããããã¯å ã®ä»»æã®æ°ã®ã¹ã¬ããããä»ã®ã¹ã¬ããã§ç¹å®ã®æ°ã®æäœãå®äºãããŸã§åŸ æ©ããŠãããã¢ã¯ãã£ããã£ãç¶ç¶ããããšãã§ããŸãã ã³ã³ã¹ãã©ã¯ã¿ãŒCountDownLatchïŒ
CountDownLatch(int count)
ïŒã¯ãããã¯ããããã¯ãããã¹ã¬ãããã解æŸãããããã«å®è¡ããå¿ èŠãããæäœã®æ°ãæž¡ãå¿ èŠããããŸãã
ããããã³ã°ãããŒã¯ãã«ãŠã³ã¿ãŒã䜿çšããŠåé€ãããŸããã¢ã¯ãã£ããªã¹ããªãŒã ã¯ãç¹å®ã®æäœãå®è¡ãããšãã«ãŠã³ã¿ãŒã®å€ãæžãããŸãã ã«ãŠã³ã¿ãŒã0ã«éãããšãåŸ æ©äžã®ãã¹ãŠã®ã¹ã¬ãããããã¯è§£é€ãããå®è¡ãç¶ç¶ãããŸãïŒäººçã®CountDownLatchã®äŸã¯ããšã¯ã¹ã«ãŒã·ã§ã³ã°ã«ãŒãã®ã³ã¬ã¯ã·ã§ã³ã§ããç¹å®ã®äººæ°ãéãŸããŸã§ããšã¯ã¹ã«ãŒã·ã§ã³ã¯éå§ãããŸããïŒã
CountDownLatchã®å ¬åŒããã¥ã¡ã³ãã
CountDownLatchã®äŸ
次ã®äŸãèããŠã¿ãŸãããã ã«ãŒã¬ãŒã¹ããããã§ãã 5å°ã®è»ãã¬ãŒã¹ã«åå ããŸãã ã¬ãŒã¹ãéå§ããã«ã¯ã次ã®æ¡ä»¶ãæºããããŠããå¿
èŠããããŸãã
CountDownLatchã¯ããŸããŸãªåæã¹ããŒã ã§äœ¿çšã§ããŸããããšãã°ã1ã€ã®ã¹ã¬ãããäœæ¥ãè¡ã£ãŠããéãä»ã®ã¹ã¬ãããåŸ æ©ãããããéã«ä»ã®ã¹ã¬ãããäœæ¥ãè¡ãã®ãåŸ æ©ããããã§ããŸãã
- 5å°ã®è»ã¯ãããããã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
- ã³ãã³ããTo startïŒããäžããããŸããã
- ã³ãã³ããèŠåïŒããäžããããŸããã
- ã³ãã³ããMarchïŒããäžããããŸããã
import java.util.concurrent.CountDownLatch; public class Race { // CountDownLatch 8 "" private static final CountDownLatch START = new CountDownLatch(8); // private static final int trackLength = 500000; public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 5; i++) { new Thread(new Car(i, (int) (Math.random() * 100 + 50))).start(); Thread.sleep(1000); } while (START.getCount() > 3) //, Thread.sleep(100); // . , 100ms Thread.sleep(1000); System.out.println(" !"); START.countDown();// , 1 Thread.sleep(1000); System.out.println("!"); START.countDown();// , 1 Thread.sleep(1000); System.out.println("!"); START.countDown();// , 1 // , // } public static class Car implements Runnable { private int carNumber; private int carSpeed;//, public Car(int carNumber, int carSpeed) { this.carNumber = carNumber; this.carSpeed = carSpeed; } @Override public void run() { try { System.out.printf(" â%d .\n", carNumber); // - // 1 START.countDown(); // await() , , , // CountDownLatch 0 START.await(); Thread.sleep(trackLength / carSpeed);// System.out.printf(" â%d !\n", carNumber); } catch (InterruptedException e) { } } } }
ããã°ã©ã ã®çµæ
1å·è»ãã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
2å·è»ã¯ã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
3å·è»ã¯ã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
4å·è»ã¯ã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
5å·è»ã¯ã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
ã¯ããã«ïŒ
泚æïŒ
3æïŒ
4å·è»ãå®æããŸããïŒ
1å·è»ãçµäºããŸããïŒ
3å·è»ãå®æããŸããïŒ
5å·è»ãå®æããŸããïŒ
2å·è»ãå®æããŸããïŒ
2å·è»ã¯ã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
3å·è»ã¯ã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
4å·è»ã¯ã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
5å·è»ã¯ã¹ã¿ãŒãã©ã€ã³ãŸã§èµ°ããŸããã
ã¯ããã«ïŒ
泚æïŒ
3æïŒ
4å·è»ãå®æããŸããïŒ
1å·è»ãçµäºããŸããïŒ
3å·è»ãå®æããŸããïŒ
5å·è»ãå®æããŸããïŒ
2å·è»ãå®æããŸããïŒ
CountDownLatchã¯ããŸããŸãªåæã¹ããŒã ã§äœ¿çšã§ããŸããããšãã°ã1ã€ã®ã¹ã¬ãããäœæ¥ãè¡ã£ãŠããéãä»ã®ã¹ã¬ãããåŸ æ©ãããããéã«ä»ã®ã¹ã¬ãããäœæ¥ãè¡ãã®ãåŸ æ©ããããã§ããŸãã
CyclicBarrier
CyclicBarrierã¯ã ããªã¢åæãã¿ãŒã³ãå®è£ ããŸãã ã«ãŒãããã¯ããªã¢ã¯ãæå®ãããæ°ã®äžŠåã¹ã¬ãããåºäŒã£ãŠãããã¯ããåæãã€ã³ãã§ãã ãã¹ãŠã®å©çãæµãããšããã«ããªãã·ã§ã³ã®ã¢ã¯ã·ã§ã³ãå®è¡ããïŒãŸãã¯ããªã¢ããããªãã§åæåãããå Žåã¯å®è¡ãããŸããïŒãå®äºåŸãããªã¢ã解é€ãããåŸ æ©äžã®ãããŒãã解æŸããããŸãã ããªã¢ã³ã³ã¹ãã©ã¯ã¿ãŒïŒ
CyclicBarrier(int parties)
ããã³
CyclicBarrier(int parties, Runnable barrierAction)
ïŒã¯ããäŒããã¹ãããŒãã£ãŒã®æ°ãšããªãã·ã§ã³ã§ãããŒãã£ãŒãäŒããšãããã ãããŒãã£ãŒãäŒãåã«çºçããã¢ã¯ã·ã§ã³ãæž¡ãå¿ èŠããããŸãã ããªãªãŒã¹ãããŸãããã
ããªã¢ã¯CountDownLatchã«äŒŒãŠããŸããã2ã€ã®äž»ãªéãã¯ãã«ãŠã³ã¿ããŒãã«ãªã£ãåŸã¯ãããã¯ããåå©çšã§ãããããªã¢ãå£ããåŸã§ãåã³äœ¿çšã§ããããšã§ãã CyclicBarrierã¯ãã¹ã¬ãããå®è¡ãããåŸã«ã®ã¿ã¹ã¬ããããåéã
join()
ã¡ãœããã®ä»£æ¿ã§ãã
CyclicBarrierã®å ¬åŒããã¥ã¡ã³ãã
CyclicBarrierã®ã±ãŒã¹ã¹ã¿ãã£
次ã®äŸãèããŠã¿ãŸãããã ãã§ãªãŒãµãŒãã¹ããããŸãã ãã§ãªãŒã¯äžåºŠã«3å°ã®è»ã茞éã§ããŸãã ãã§ãªãŒãå床é転ããªãããã«ããã«ã¯ãå°ãªããšã3å°ã®è»ã亀差ç¹ã«éãŸããšãã«ãã§ãªãŒãéãå¿
èŠããããŸãã
3ã€ã®ã¹ããªãŒã ã
ã¡ãœããã«å°éãããšãããªã¢ã¢ã¯ã·ã§ã³ãããªã¬ãŒãããèç©ããããã§ãªãŒããã®3å°ã®è»ããã§ãªãŒãããŸãã ãã®åŸãæ°ãããµã€ã¯ã«ãå§ãŸããŸãã
import java.util.concurrent.CyclicBarrier; public class Ferry { private static final CyclicBarrier BARRIER = new CyclicBarrier(3, new FerryBoat()); // , , // . , . public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 9; i++) { new Thread(new Car(i)).start(); Thread.sleep(400); } } //, public static class FerryBoat implements Runnable { @Override public void run() { try { Thread.sleep(500); System.out.println(" !"); } catch (InterruptedException e) { } } } //, public static class Car implements Runnable { private int carNumber; public Car(int carNumber) { this.carNumber = carNumber; } @Override public void run() { try { System.out.printf(" â%d .\n", carNumber); // , await() // , BARRIER.await(); System.out.printf(" â%d .\n", carNumber); } catch (Exception e) { } } } }
ããã°ã©ã ã®çµæ
è»çªå·0ã¯ãã§ãªãŒãŸã§é転ããŸããã
1å·è»ããã§ãªãŒãŸã§é転ããŸããã
2å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
3å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
ãã§ãªãŒãã§ãªãŒã«ãŒïŒ
2å·è»ã¯åãç¶ããŸããã
1å·è»ã¯åãç¶ããŸããã
è»çªå·0ã¯åãç¶ããŸããã
4å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
5å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
6å·è»ããã§ãªãŒãŸã§é転ããŸããã
ãã§ãªãŒãã§ãªãŒã«ãŒïŒ
5å·è»ã¯åãç¶ããŸããã
4å·è»ã¯åãç¶ããŸããã
3å·è»ã¯åãç¶ããŸããã
7å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
8å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
ãã§ãªãŒãã§ãªãŒã«ãŒïŒ
8å·è»ã¯åãç¶ããŸããã
6å·è»ã¯åãç¶ããŸããã
7å·è»ã¯åãç¶ããŸããã
1å·è»ããã§ãªãŒãŸã§é転ããŸããã
2å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
3å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
ãã§ãªãŒãã§ãªãŒã«ãŒïŒ
2å·è»ã¯åãç¶ããŸããã
1å·è»ã¯åãç¶ããŸããã
è»çªå·0ã¯åãç¶ããŸããã
4å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
5å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
6å·è»ããã§ãªãŒãŸã§é転ããŸããã
ãã§ãªãŒãã§ãªãŒã«ãŒïŒ
5å·è»ã¯åãç¶ããŸããã
4å·è»ã¯åãç¶ããŸããã
3å·è»ã¯åãç¶ããŸããã
7å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
8å·è»ããã§ãªãŒãŸã§èµ°ããŸããã
ãã§ãªãŒãã§ãªãŒã«ãŒïŒ
8å·è»ã¯åãç¶ããŸããã
6å·è»ã¯åãç¶ããŸããã
7å·è»ã¯åãç¶ããŸããã
3ã€ã®ã¹ããªãŒã ã
await()
ã¡ãœããã«å°éãããšãããªã¢ã¢ã¯ã·ã§ã³ãããªã¬ãŒãããèç©ããããã§ãªãŒããã®3å°ã®è»ããã§ãªãŒãããŸãã ãã®åŸãæ°ãããµã€ã¯ã«ãå§ãŸããŸãã
ãšã¯ã¹ãã§ã³ãžã£ãŒ<V>
äž¡æ¹ã®ã¹ããªãŒã ã®æäœã®ããæç¹ã§ã2ã€ã®ã¹ããªãŒã éã§ããŒã¿ã亀æããã«ã¯ã亀ææ©ïŒäº€ææ©ïŒãå¿ èŠã«ãªãå ŽåããããŸãã ãšã¯ã¹ãã§ã³ãžã£ãŒã¯äžè¬åãããã¯ã©ã¹ã§ããã転éãããªããžã§ã¯ãã®ã¿ã€ãã«ãã£ãŠãã©ã¡ãŒã¿ãŒåãããŸãã
ãšã¯ã¹ãã§ã³ãžã£ãŒã¯ãã¹ã¬ããã®ãã¢ã®åæãã€ã³ãã§ãã
exchange()
ã¡ãœãããåŒã³åºãã¹ã¬ãã
exchange()
ãããã¯ãããå¥ã®ã¹ã¬ãããåŸ æ©ããŸãã å¥ã®ã¹ã¬ãããåãã¡ãœãããåŒã³åºããšããªããžã§ã¯ãã亀æãããŸããåãªããžã§ã¯ãã¯ã
exchange()
ã¡ãœããã§ä»ã®ãªããžã§ã¯ããžã®åŒæ°ãåãåããŸãã 亀ææ©ã
null
å€ã®è»¢éããµããŒãããŠããããšã¯æ³šç®ã«å€ããŸãã ããã«ããããªããžã§ã¯ããäžæ¹åã«ããŸãã¯åçŽã«2ã€ã®ã¹ããªãŒã ã®åæãã€ã³ããšããŠè»¢éããããšãã§ããŸãã
Exchangerã®å ¬åŒããã¥ã¡ã³ãã
ãšã¯ã¹ãã§ã³ãžã£ãŒã®äŸ
次ã®äŸãèããŠã¿ãŸãããã 2ã€ã®ãã©ãã¯ããããŸãïŒ1ã€ã¯ãã€ã³ãAãããã€ã³ãDã«ããã1ã€ã¯ãã€ã³ãBãããã€ã³ãCã«è¡ããŸããéè·¯ADãšBCã¯ãã€ã³ãEã§äº€å·®ããŸãããã€ã³ãAãšBãããè·ç©ã¯ãã€ã³ãCãšDã«é
éãããŸãããã®ããããã€ã³ãEã®ãã©ãã¯é¢é£ããããã±ãŒãžãæºããã亀æããå¿
èŠããããŸãã
ã芧ã®ãšããã1å°ã®ãã©ãã¯ïŒ1ã€ã®ã¹ããªãŒã ïŒããã€ã³ãEïŒåæãã€ã³ãã«å°éïŒã«å°çãããšãå¥ã®ãã©ãã¯ïŒå¥ã®ã¹ããªãŒã ïŒããã€ã³ãEïŒåæãã€ã³ãã«å°éïŒã«å°éãããŸã§åŸ æ©ããŸãã ãã®åŸãå°å 亀æãè¡ããïŒã¹ããªã³ã°ïŒãäž¡æ¹ã®ãã©ãã¯ïŒã¹ããªãŒã ïŒããã¹ïŒäœæ¥ïŒãç¶ç¶ããŸãã
import java.util.concurrent.Exchanger; public class Delivery { // , String private static final Exchanger<String> EXCHANGER = new Exchanger<>(); public static void main(String[] args) throws InterruptedException { String[] p1 = new String[]{"{ A->D}", "{ A->C}"};// 1- String[] p2 = new String[]{"{ B->C}", "{ B->D}"};// 2- new Thread(new Truck(1, "A", "D", p1)).start();// 1- D Thread.sleep(100); new Thread(new Truck(2, "B", "C", p2)).start();// 2- } public static class Truck implements Runnable { private int number; private String dep; private String dest; private String[] parcels; public Truck(int number, String departure, String destination, String[] parcels) { this.number = number; this.dep = departure; this.dest = destination; this.parcels = parcels; } @Override public void run() { try { System.out.printf(" â%d : %s %s.\n", number, parcels[0], parcels[1]); System.out.printf(" â%d %s %s.\n", number, dep, dest); Thread.sleep(1000 + (long) Math.random() * 5000); System.out.printf(" â%d .\n", number); parcels[1] = EXCHANGER.exchange(parcels[1]);// exchange() // exchange(), System.out.printf(" â%d %s.\n", number, dest); Thread.sleep(1000 + (long) Math.random() * 5000); System.out.printf(" â%d %s : %s %s.\n", number, dest, parcels[0], parcels[1]); } catch (InterruptedException e) { } } } }
ããã°ã©ã ã®çµæ
以äžããã©ãã¯1çªã«ç©èŒãããŸããïŒ{ããã±ãŒãžA-> D}ããã³{ããã±ãŒãžA-> C}ã
ãã©ãã¯No. 1ã¯ããã€ã³ãAãããã€ã³ãDãŸã§é転ããŸããã
ãã©ãã¯No. 2ã«æèŒïŒ{ããã±ãŒãžB-> C}ããã³{ããã±ãŒãžB-> D}ã
ãã©ãã¯ïŒ2ã¯ããã€ã³ãBãããã€ã³ãCãŸã§é転ããŸããã
ãã©ãã¯1çªããã€ã³ãEã«å°çããŸããã
ãã©ãã¯No. 2ã¯ãã€ã³ãEã«å°çããŸããã
ã¢ã€ãã Cã®ãã©ãã¯ã¯ãã©ãã¯2ã«ç§»åããŸããã
ã¢ã€ãã Dã®ãã©ãã¯ã¯ãã©ãã¯1ã«ç§»åããŸããã
ãã©ãã¯No. 2ãCã«å°çããé éãããŸããïŒ{ããã±ãŒãžB-> C}ããã³{ããã±ãŒãžA-> C}ã
ãã©ãã¯No. 1ãDã«å°çããé éãããŸããïŒ{ããã±ãŒãžA-> D}ããã³{ããã±ãŒãžB-> D}ã
ãã©ãã¯No. 1ã¯ããã€ã³ãAãããã€ã³ãDãŸã§é転ããŸããã
ãã©ãã¯No. 2ã«æèŒïŒ{ããã±ãŒãžB-> C}ããã³{ããã±ãŒãžB-> D}ã
ãã©ãã¯ïŒ2ã¯ããã€ã³ãBãããã€ã³ãCãŸã§é転ããŸããã
ãã©ãã¯1çªããã€ã³ãEã«å°çããŸããã
ãã©ãã¯No. 2ã¯ãã€ã³ãEã«å°çããŸããã
ã¢ã€ãã Cã®ãã©ãã¯ã¯ãã©ãã¯2ã«ç§»åããŸããã
ã¢ã€ãã Dã®ãã©ãã¯ã¯ãã©ãã¯1ã«ç§»åããŸããã
ãã©ãã¯No. 2ãCã«å°çããé éãããŸããïŒ{ããã±ãŒãžB-> C}ããã³{ããã±ãŒãžA-> C}ã
ãã©ãã¯No. 1ãDã«å°çããé éãããŸããïŒ{ããã±ãŒãžA-> D}ããã³{ããã±ãŒãžB-> D}ã
ã芧ã®ãšããã1å°ã®ãã©ãã¯ïŒ1ã€ã®ã¹ããªãŒã ïŒããã€ã³ãEïŒåæãã€ã³ãã«å°éïŒã«å°çãããšãå¥ã®ãã©ãã¯ïŒå¥ã®ã¹ããªãŒã ïŒããã€ã³ãEïŒåæãã€ã³ãã«å°éïŒã«å°éãããŸã§åŸ æ©ããŸãã ãã®åŸãå°å 亀æãè¡ããïŒã¹ããªã³ã°ïŒãäž¡æ¹ã®ãã©ãã¯ïŒã¹ããªãŒã ïŒããã¹ïŒäœæ¥ïŒãç¶ç¶ããŸãã
ãã§ã€ã¶ãŒ
CyclicBarrierã®ãããªPhaserïŒphaserïŒã¯ã Barrieråæãã¿ãŒã³ã®å®è£ ã§ãããCyclicBarrierãšã¯ç°ãªããããæè»æ§ããããŸãã ãã®ã¯ã©ã¹ã䜿çšãããšãå ±éã¢ã¯ã·ã§ã³ã®åäžã®ãã§ãŒãºãŸãã¯ã¹ããŒãžãè¡šãã¹ã¬ãããåæã§ããŸãã CyclicBarrierãšåæ§ã«ãPhaserã¯ã¡ã³ããŒã¹ããªãŒã ãåºäŒãåæãã€ã³ãã§ãã ãã¹ãŠã®é¢ä¿è ãå°çãããšãPhaserã¯æ¬¡ã®ãã§ãŒãºã«é²ã¿ãåã³å®äºããã®ãåŸ ã¡ãŸãã
PhaserãšCyclicBarrierãæ¯èŒãããšãPhaserã®æ¬¡ã®éèŠãªæ©èœã匷調ã§ããŸãã
- åãã§ãŒãºïŒåæãµã€ã¯ã«ïŒã«ã¯çªå·ããããŸãã
- åå è ã®æ°ã¯å³å¯ã«èšå®ãããŠããããç°ãªãå ŽåããããŸãããããŒã¯åå è ãšããŠç»é²ããããã®åå ãåãæ¶ãå ŽåããããŸãã
- åå è ã¯ãä»ã®ãã¹ãŠã®åå è ãããªã¢ã«éãŸããŸã§åŸ ã€å¿ èŠã¯ãããŸããã ä»äºãç¶ããã«ã¯ãå°çã«ã€ããŠç¥ãããã ãã§ååã§ãã
- ã©ã³ãã ãªç®æè ã¯ãããªã¢å ã®ã¢ã¯ãã£ããã£ãç£èŠã§ããŸãã
- ãããŒã¯ããããå æãããããšãæåŸ ããããã«ãããªã¢ã®åœäºè ã§ã¯ãªãå ŽåããããŸãã
- ãã§ã€ã¶ãŒã«ã¯ãªãã·ã§ã³ã®ã¢ã¯ã·ã§ã³ã¯ãããŸããã
Phaserãªããžã§ã¯ãã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã®ããããã䜿çšããŠäœæãããŸãã
Phaser() Phaser(int parties)
Partyãã©ã¡ãŒã¿ãŒã¯ãã¢ã¯ã·ã§ã³ã®ãã§ãŒãºãå®è¡ããããŒãã£ãŒã®æ°ã瀺ããŸãã æåã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãåŽé¢ã®ãªãPhaserãªããžã§ã¯ããäœæãããã®å Žåã®ããªã¢ããéããããŸããã 2çªç®ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ããããµã€ãã®æ°ãç»é²ããŸãã ããªã¢ã¯ããã¹ãŠã®é¢ä¿è ãå°çãããšãããŸãã¯æåŸã®åå è ãåé€ããããšãã«éããŸãã ïŒPhaserã¯ã©ã¹ã«ã¯ããŸã 芪Phaserãªããžã§ã¯ããæž¡ãããã³ã³ã¹ãã©ã¯ã¿ããããŸããããããã¯èæ ®ããŸãããïŒ
äž»ãªæ¹æ³ïŒ
- int registerïŒïŒ -ãã§ãŒãºãå®è¡ããæ°ããã¡ã³ããŒãç»é²ããŸãã çŸåšã®ãã§ãŒãºçªå·ãè¿ããŸãã
- int getPhaseïŒïŒ -çŸåšã®ãã§ãŒãºã®çªå·ãè¿ããŸãã
- int reachAndAwaitAdvanceïŒïŒ -ã¹ã¬ããããã§ãŒãºãå®äºããããšã瀺ããŸãã ä»ã®ãã¹ãŠã®é¢ä¿è
ããã®ãã§ãŒãºãå®äºãããŸã§ããããŒã¯äžæãããŸãã
CyclicBarrier.await()
æ£ç¢ºãªå¯Ÿå¿ç©ã çŸåšã®ãã§ãŒãºçªå·ãè¿ããŸãã - int ArrivateïŒïŒ -ããŒãã£ããã§ãŒãºãå®äºããããšãå ±åãããã§ãŒãºçªå·ãè¿ããŸãã ãã®ã¡ãœãããåŒã³åºããããšãã¹ã¬ããã¯åæ¢ããŸããããå®è¡ãç¶ç¶ããŸãã
- int ArrivedAndDeregisterïŒïŒ -ããŒãã£ã«ãããã¹ãŠã®ãã§ãŒãºã®å®äºãå ±åããç»é²ããåé€ããŸãã çŸåšã®ãã§ãŒãºçªå·ãè¿ããŸãã
- int awaitAdvanceïŒint phaseïŒ-phaseãçŸåšã®ãã§ãŒãºã®æ°ãšçããå Žåããããçºçããã¹ã¬ãããçµäºãããŸã§äžæåæ¢ããŸãã ãã以å€ã®å Žåã¯ãããã«åŒæ°ãè¿ããŸãã
Phaserã®å ¬åŒããã¥ã¡ã³ãã
ãã§ã€ã¶ãŒã®äŸ
次ã®äŸãèããŠã¿ãŸãããã 5ã€ã®åçæããããŸãã æåã®4人ã¯ä¹å®¢ãç«ãããŠãã¹ãåŸ
ã€ããšãã§ããŸãã ãã¹ã¯å
¬åãåºãŠãååçæã§ãã°ããæ¢ãŸããŸãã æçµåè»åŸããã¹ã¯å
¬åã«è¡ããŸãã ä¹å®¢ãè¿ããé©åãªåçæã§éããå¿
èŠããããŸãã
import java.util.ArrayList; import java.util.concurrent.Phaser; public class Bus { private static final Phaser PHASER = new Phaser(1);// // 0 6 - , 1 - 5 public static void main(String[] args) throws InterruptedException { ArrayList<Passenger> passengers = new ArrayList<>(); for (int i = 1; i < 5; i++) { // if ((int) (Math.random() * 2) > 0) passengers.add(new Passenger(i, i + 1));// if ((int) (Math.random() * 2) > 0) passengers.add(new Passenger(i, 5)); // } for (int i = 0; i < 7; i++) { switch (i) { case 0: System.out.println(" ."); PHASER.arrive();// 0 1 - break; case 6: System.out.println(" ."); PHASER.arriveAndDeregister();// , break; default: int currentBusStop = PHASER.getPhase(); System.out.println(" â " + currentBusStop); for (Passenger p : passengers) //, if (p.departure == currentBusStop) { PHASER.register();// , p.start(); // } PHASER.arriveAndAwaitAdvance();// } } } public static class Passenger extends Thread { private int departure; private int destination; public Passenger(int departure, int destination) { this.departure = departure; this.destination = destination; System.out.println(this + " â " + this.departure); } @Override public void run() { try { System.out.println(this + " ."); while (PHASER.getPhase() < destination) // () PHASER.arriveAndAwaitAdvance(); // Thread.sleep(1); System.out.println(this + " ."); PHASER.arriveAndDeregister(); // } catch (InterruptedException e) { } } @Override public String toString() { return "{" + departure + " -> " + destination + '}'; } } }
ããã°ã©ã ã®çµæ
ä¹å®¢{1-> 2}ã¯ã¹ãããçªå·1ã§åŸ
ã£ãŠããŸã
ä¹å®¢{1-> 5}ã¯ãã¹ãããçªå·1ã§åŸ ã£ãŠããŸã
ä¹å®¢{2-> 3}ã¯ã¹ãããçªå·2ã§åŸ ã£ãŠããŸã
ä¹å®¢{2-> 5}ã¯ã¹ãããçªå·2ã§åŸ ã£ãŠããŸã
ä¹å®¢{3-> 4}ã¯ã¹ãããçªå·3ã§åŸ ã£ãŠããŸã
ä¹å®¢{4-> 5}ã¯ã¹ãããçªå·4ã§åŸ ã£ãŠããŸã
ä¹å®¢{4-> 5}ã¯ã¹ãããçªå·4ã§åŸ ã£ãŠããŸã
ãã¹ã¯å ¬åãåºçºããŸããã
ã¹ããããã³ããŒ1
ä¹å®¢{1-> 5}ããã¹ã«ä¹ã蟌ãã ã
ä¹å®¢{1-> 2}ããã¹ã«ä¹ã蟌ã¿ãŸããã
ã¹ããããã³ããŒ2
ä¹å®¢{2-> 3}ããã¹ã«ä¹ã蟌ãã ã
{1 -> 2} .
{2 -> 5} .
â 3
{2 -> 3} .
{3 -> 4} .
â 4
{4 -> 5} .
{3 -> 4} .
{4 -> 5} .
â 5
{1 -> 5} .
{2 -> 5} .
{4 -> 5} .
{4 -> 5} .
.
ä¹å®¢{1-> 5}ã¯ãã¹ãããçªå·1ã§åŸ ã£ãŠããŸã
ä¹å®¢{2-> 3}ã¯ã¹ãããçªå·2ã§åŸ ã£ãŠããŸã
ä¹å®¢{2-> 5}ã¯ã¹ãããçªå·2ã§åŸ ã£ãŠããŸã
ä¹å®¢{3-> 4}ã¯ã¹ãããçªå·3ã§åŸ ã£ãŠããŸã
ä¹å®¢{4-> 5}ã¯ã¹ãããçªå·4ã§åŸ ã£ãŠããŸã
ä¹å®¢{4-> 5}ã¯ã¹ãããçªå·4ã§åŸ ã£ãŠããŸã
ãã¹ã¯å ¬åãåºçºããŸããã
ã¹ããããã³ããŒ1
ä¹å®¢{1-> 5}ããã¹ã«ä¹ã蟌ãã ã
ä¹å®¢{1-> 2}ããã¹ã«ä¹ã蟌ã¿ãŸããã
ã¹ããããã³ããŒ2
ä¹å®¢{2-> 3}ããã¹ã«ä¹ã蟌ãã ã
{1 -> 2} .
{2 -> 5} .
â 3
{2 -> 3} .
{3 -> 4} .
â 4
{4 -> 5} .
{3 -> 4} .
{4 -> 5} .
â 5
{1 -> 5} .
{2 -> 5} .
{4 -> 5} .
{4 -> 5} .
.
ãšããã§ããã§ã€ã¶ãŒæ©èœã¯CountDownLatchã®åäœãåçŸã§ããŸãã
Phaserã䜿çšããCountDownLatchã®äŸ
import java.util.concurrent.Phaser; public class NewRace { private static final Phaser START = new Phaser(8); private static final int trackLength = 500000; public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 5; i++) { new Thread(new Car(i, (int) (Math.random() * 100 + 50))).start(); Thread.sleep(100); } while (START.getRegisteredParties() > 3) //, Thread.sleep(100); // . , 100ms Thread.sleep(100); System.out.println(" !"); START.arriveAndDeregister(); Thread.sleep(100); System.out.println("!"); START.arriveAndDeregister(); Thread.sleep(100); System.out.println("!"); START.arriveAndDeregister(); } public static class Car implements Runnable { private int carNumber; private int carSpeed; public Car(int carNumber, int carSpeed) { this.carNumber = carNumber; this.carSpeed = carSpeed; } @Override public void run() { try { System.out.printf(" â%d .\n", carNumber); START.arriveAndDeregister(); START.awaitAdvance(0); Thread.sleep(trackLength / carSpeed); System.out.printf(" â%d !\n", carNumber); } catch (InterruptedException e) { } } } }
誰ããéå®ããŠããããããšãŠãå¬ããã§ã=ïŒ
Phaserã®è©³çŽ°ã¯ãã¡ãã
ã·ã³ã¯ããã€ã¶ãŒã®è©³çŽ°ãšäŸãåç §ããã«ã¯ããã¡ããã芧ãã ããã
java.util.concurrentã®åªããæŠèŠã¯ãã¡ããã芧ãã ããã