ã¿ã¹ã¯ãããã¥ãŒãµãŒ/ã³ã³ã·ã¥ãŒããŒ
ãã®èšäºã¯ãJAVAã®ãã«ãã¹ã¬ããã®äžçã«æè¿ç²Ÿéããåå¿è
ã察象ãšããŠããŸãã
å°ãåãŸã§ãç§ã¯EPAMã§ã€ã³ã¿ãŒã³ã·ãããè¡ããŸãããè¥ãããã¯ã³ãå®äºããããã«å¿
èŠãªã¿ã¹ã¯ã®ãªã¹ãã«ã¯ããã«ãã¹ã¬ããã®å²ãåœãŠããããŸããã å
¬å¹³ã«èšãã°ãArrayBlockingQueueãSemophoreãããã³äžè¬çã«åŒ·åãªAPIïŒjava.util.concurrentïŒã倧ããªããªãã¯ãªãã§äœ¿çšã§ããå ŽåãwaitïŒïŒãnotifyïŒïŒãªã©ã®äœã¬ãã«ã®ããŒã«ã§ãããè¡ãããšã匷å¶ããã人ã¯ããŸããã ããã«ããã«ãã¹ã¬ããã·ããªãªã«å¯Ÿå¿ãã代ããã«ãèªè»¢è»ãåçºæããäžæ¹ã§ãAPIã䞊ååŠçã®å§åçãªè€éããé ããŠããå Žåã¯ãæªãç¿æ
£ãšèŠãªãããŸãã APIã䜿çšããŠäž¡æ¹ã®ãã€ãã£ããªãã·ã§ã³ãå®è£
ããŸããã ä»æ¥ã¯1ã€ã®ãªãã·ã§ã³ã瀺ããŸãã
æå§ãã«ã
次ã®èšäºãèªãããšããå§ãããŸãã
ãã®ãããžã§ã¯ããžã®ãªã³ã¯ ã
å²ãåœãŠã¯æ¬¡ã®ãšããã§ããã- ãã³ãã«ã«åãã£ãŠèªè¡ãã次ã«ããããçš®é¡ã®ååãç©ã¿èŸŒãããã«ããŒã¹ã«èªè¡ãã茞éè¹ããããŸãã
- 圌ãã¯äžåºŠã«5é»ã®è¹ããå
¥ããªãçããã³ãã«ãééããŸãã ããã³ãã«ãŸã§æ³³ãããšããèšèã¯ãè¹ãã©ããããçŸããªããã°ãªããªãããšãæå³ããŸãã å¶éãããæ°ïŒ10ãŸãã¯100ïŒã«ããããšããç¡éæ°ã«ããããšãã§ããŸãã ãæ°Žæ³³ããšããèšèãè¹ã®çºé»æ©ãšåŒã³ãŸãã
- è¹ã®çš®é¡ãšå®¹éã¯ãè¹ã«ç©ã¿èŸŒãå¿
èŠãããååã®çš®é¡ã«ãã£ãŠç°ãªãå ŽåããããŸãã ã€ãŸããTKã«ã€ããŠã¯ã3çš®é¡ã®è¹ïŒãã³ãããããè¡£é¡ïŒãš3çš®é¡ã®å®¹é10ã50ã100åãæãã€ããŸããã ååã 3çš®é¡ã®è¹* 3çš®é¡ã®å®¹é= 9çš®é¡ã®è¹ã
- ããã«ãè¹ã«ç©ã¿èŸŒãããã®å¯å°ã«ã¯ããã³ãããããè¡£é¡ã®3çš®é¡ããããŸãã åããŒã¹ã¯ãèªåãå¿
èŠãšããè¹ãåãåããããèªäœãåŒã³åºããŠãç©ã¿èŸŒã¿ãéå§ããŸãã 1ç§ã§ãæ¡æ©ã¯10ãŠããããè¹ã«ç©ã¿èŸŒã¿ãŸãã ååã ã€ãŸããè¹ã«50åã®å®¹éãããå ŽåãããŒã¹ã¯5ç§éã®æäœã§ãããç©ã¿èŸŒã¿ãŸãã
èŠä»¶ã¯æ¬¡ã®ãšããã§ãã- ã¿ã¹ã¯ã䞊ååŠçã«æ£ããåå²ããŸãã
- ã¹ããªãŒã ãåæããããŒã¿ã®æŽåæ§ãç¶æããŸãã çµå±ã®ãšãããå
±æãªãœãŒã¹ãžã®ã¹ã¬ããã®ã¢ã¯ã»ã¹ãå¶éããããšã¯é£ãããããŸããããããããå調ããŠåäœãããããšã¯ãã§ã«ã¯ããã«å°é£ã§ãã
- è¹è¶çºé»æ©ã®æäœã¯ãããŒã¹ã®äœæ¥ã«äŸåããã¹ãã§ã¯ãªãããã®éãåæ§ã§ãã
- å
±æãªãœãŒã¹ã¯ã¹ã¬ããã»ãŒãã§ããå¿
èŠããããŸãïŒå®è£
ã«ãªãœãŒã¹ãããå ŽåïŒ
- ã¿ã¹ã¯ããªãå Žåãã¹ã¬ãããã¢ã¯ãã£ãã«ããªãã§ãã ããã
- ã¿ã¹ã¯ããªãå Žåãã¹ã¬ããã¯ãã¥ãŒããã¯ã¹ãä¿æãã¹ãã§ã¯ãããŸããã
ãããè¡ããïŒ
ãŸããå³ãæããŠãäœãäœã§ããããæ確ã«ããŸããã

åé¡ã解決ããåã«ãçŽã®è¡šé¢ã§èŠèŠåããããšããå§ãããŸãã ç¹ã«ããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®å Žåã
ã¢ããªã±ãŒã·ã§ã³ãã³ã³ããŒãã³ãããã®å Žåã¯ã¯ã©ã¹ã«åå²ããŸãããã ãããžã§ã¯ãæ§é ã
ã¯ã©ã¹-ã·ããã¯ã©ã¹èªäœã«ã¯ããžãã¯ãå«ãŸããŠããŸããã ããžã§ã
ãœãŒã¹ã³ãŒãpublic class Ship { private int count; private Size size; private Type type; public Ship(Size size, Type type) { this.size = size; this.type = type; } public void add(int count) { this.count += count; } public boolean countCheck() { if (count >= size.getValue()) { return false; } return true; } public int getCount() { return count; } public Type getType() { return type; } public Size getSize() { return size; } }
è¹ã¯ãµã€ãºãšã¿ã€ããç°ãªããããEnumã¯ã©ã¹ãäœæããŠè¹ã®ããããã£ã決å®ããããšã«ããŸããã ãµã€ãºãšã¿ã€ãã ãµã€ãºã«ã¯å®çŸ©æžã¿ã®ããããã£ããããŸãã ïŒã³ãŒãïŒ
Shipã¯ã©ã¹ã«ã¯intã«ãŠã³ã¿ãŒããããæ¢ã«äœåã®ååãããŒããããŠããããè¹ã®ããããã£ã§ç€ºãããŠãã以äžã®å Žåãåãã¯ã©ã¹ã®boolean countCheckïŒïŒã¡ãœããã¯falseãè¿ããŸããã€ãŸããè¹ãããŒããããŸãã
ã¯ã©ã¹-ãã³ãã«ãœãŒã¹ã³ãŒã public class Tunnel { private List<Ship> store; private static final int maxShipsInTunel = 5; private static final int minShipsInTunel = 0; private int shipsCounter = 0; public Tunnel() { store = new ArrayList<>(); } public synchronized boolean add(Ship element) { try { if (shipsCounter < maxShipsInTunel) { notifyAll(); store.add(element); String info = String.format("%s + The ship arrived in the tunnel: %s %s %s", store.size(), element.getType(), element.getSize(), Thread.currentThread().getName()); System.out.println(info); shipsCounter++; } else { System.out.println(store.size() + "> There is no place for a ship in the tunnel: " + Thread.currentThread().getName()); wait(); return false; } } catch (InterruptedException e) { e.printStackTrace(); } return true; } public synchronized Ship get(Type shipType) { try { if (shipsCounter > minShipsInTunel) { notifyAll(); for (Ship ship : store) { if (ship.getType() == shipType) { shipsCounter--; System.out.println(store.size() + "- The ship is taken from the tunnel: " + Thread.currentThread().getName()); store.remove(ship); return ship; } } } System.out.println("0 < There are no ships in the tunnel"); wait(); } catch (InterruptedException e) { e.printStackTrace(); } return null; }
ãã³ãã«ã«ã¯ããŒããæ ŒçŽãããŸããããã¯ãªã¹ãã䜿çšããŠè¡ãããŸãã 容éã¯5ããŒãããã³ãã«ããŸãã äœããã®æ¹æ³ã§ããã³ãã«ã«ããŒããè¿œå ããŠãããããåãåºãå¿
èŠããããŸãã 2ã€ã®addïŒïŒããã³getïŒïŒã¡ãœããããããè¡ããŸãã getïŒïŒã¡ãœããã¯ãå¿
èŠãªã¿ã€ãã«å¿ããŠãªã¹ãããããŒããååŸããã³åé€ããŸãã addïŒïŒããã³getïŒïŒã¡ãœãããèŠããšãããããã«ããªã¹ãå
ã®è¹ã®æ°ããã§ãã¯ãããŸãã ship> 5ã®å ŽåãããŒãã®è¿œå ã¯æ©èœãããéã«ship <0ã®å Žåã¯ãªã¹ãã®ååŸãæ©èœããŸããã ãã³ãã«ã¯ããã«ãã¹ã¬ããã®ã³ã³ããã¹ãã«ãããå
±æãªãœãŒã¹ã§ãã ãã«ãã¹ã¬ããã®å
±æãªãœãŒã¹ã¯æªã§ãã ãã«ãã¹ã¬ããããã°ã©ãã³ã°ã®ãã¹ãŠã®åé¡ãšè€éãã¯ããŸãã«å
±æãªãœãŒã¹ã«ç±æ¥ããŠããŸãã ãããã£ãŠããããã¯é¿ããå¿
èŠããããŸãã
ç¹ã«å
±æãªãœãŒã¹ã®åé¡ã¯äœã§ããã
ãŸããããŒãã®è¿œå ãšååŸã¯ã¹ã¬ããéã§äžè²«ããŠããå¿
èŠããããŸãã äžè²«æ§ããªãå Žåã競åç¶æ
ãšããŒã¿æ倱ã®
å¯èœæ§ã
é«ããªããŸãã
synchronizedããŒã¯ãŒãã§ããã解決ããŸãã
第äºã«ãTKã¯èšåããŸããïŒ
-ã¿ã¹ã¯ããªãå Žåãã¹ããªãŒã ãã¢ã¯ãã£ãã«ããªãã§ãã ããã
-ã¿ã¹ã¯ããªãå Žåãã¹ããªãŒã ã¯ãã¥ãŒããã¯ã¹ãä¿æããŸããã
ãã®ããã«ãwaitïŒïŒããã³notifyAllïŒïŒã®åœ¢åŒã®
ãœãªã¥ãŒã·ã§ã³ã
ãããŸã ã
addïŒïŒã¡ãœãããšããã¿ã¹ã¯ãªãããšãããã¬ãŒãºãå®è¡ããã¹ã¬ããã®å Žåãship> 5ãæå³ããŸãã ship> 5ã®å Žåãã¹ã¬ããã¯ã¢ã¯ãã£ããã£ãåæ¢ããŠåŸ
æ©ããå¿
èŠããããŸãã ã¹ã¬ãããåæ¢ããŠãã¥ãŒããã¯ã¹ãåé€ããããã«ãwaitïŒïŒãåŒã³åºããŸãã getïŒïŒã¡ãœããã«ãåæ§ã®ã«ãŒã«ããããŸãã ããã®ããã«ã®ã¿<0ãåºè·ããŸãã åŸ
ã£ãŠã圌ãã¯åŸ
ã€ã ããããã©ããã£ãŠåœŒããç®èŠããããä»äºã«æ»ããšèšãã®ãïŒ ããã§ãnotifyAllïŒïŒã¡ãœããã圹ç«ã¡ãŸãã 圌女ã®ä»äºã¯ãã¹ã¬ãããåŸ
æ©ããå®è¡å¯èœã«åãæ¿ããããšã§ãã addïŒïŒã¡ãœãããèµ·åããåæã«<5ãåºè·ãããšãgetïŒïŒã¡ãœããã§åäœããã¹ã¬ãããèµ·åããŸãã éã«ãgetïŒïŒã¡ãœãããããªã¬ãŒãããship> 0ã®å ŽåãaddïŒïŒã¡ãœããã§åäœããã¹ããªãŒã ãèµ·åããŸãã äœããã®ååž°...ãããã泚æããŠãã ããïŒ DEADLOCKããã£ããããŠãç¡éã®åŸ
æ©ã«å
¥ãå¯èœæ§ããããŸãã ïŒhttp://www.quizful.net/interview/java/DeadlockïŒ
ããã«é²ã...
ã¯ã©ã¹-ShipGeneratorãããã§ãããŒããçæããç¬ç«ãããããŒã§ãããè¡ããã®ãå¿
èŠã§ãã ã¯ã©ã¹ShipGeneratorã
ãœãŒã¹ã³ãŒã public class ShipGenerator implements Runnable { private Tunnel tunnel; private int shipCount; public ShipGenerator(Tunnel tunnel, int shipCount) { this.tunnel = tunnel; this.shipCount = shipCount; } @Override public void run() { int count = 0; while (count < shipCount) { Thread.currentThread().setName(" Generator ship"); count++; tunnel.add(new Ship(getRandomSize(), getRandomType())); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } private Type getRandomType() { Random random = new Random(); return Type.values()[random.nextInt(Type.values().length)]; } private Size getRandomSize() { Random random = new Random(); return Size.values()[random.nextInt(Size.values().length)]; } }
ããŒããçæããã¿ã¹ã¯ãã¹ããªãŒã ã«è¿œå ããã«ã¯ãRunnableã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããå¿
èŠããããŸãã 2ã€ã®ãã©ã¡ãŒã¿ãŒãå
¥åãããšãTunnelãšäžä»£ã«å¿
èŠãªè¹ã®æ°ã«ãªããŸãã 次ã«ãrunïŒïŒã¡ãœããããªãŒããŒã©ã€ãããŸãã runïŒïŒã¡ãœããã¯ãã¹ã¬ããã«ãã£ãŠçŽæ¥å®è¡ãããã¡ãœããã§ãã ããã§ãè¹è¶ãçæããããã®ããžãã¯ãé
眮ããŸãã ããžãã¯ã¯åçŽã§ãã Randomã䜿çšããŠããŒããã©ã³ãã ã«çæããTunnelå
±æãªãœãŒã¹ã«å
¥ããŸãã
å°ããªäœè«ã å€ãã®äººã誀ã£ãŠRunnableã€ã³ã¿ãŒãã§ãŒã¹ãäœæããããšã§ã¹ã¬ãããäœæãããšä¿¡ããŠãããããã¹ã¬ããã«ã¿ã¹ã¯ãè¿œå ããå¿
èŠããããšèšããŸããã å®éã圌ãã¯ãããŒã®ã¿ã¹ã¯ãäœæããŸãã ã€ãŸããRunnableã€ã³ã¿ãŒãã§ãŒã¹ãå®è£
ããã¯ã©ã¹ã1000åäœæããŠããã¹ã¬ããã1000åäœæããããšã«ã¯ãªããŸããã ããã¯ã1000åã®ã¿ã¹ã¯ãäœæããããšãæå³ããŸãã ãããŠããããã®ã¿ã¹ã¯ãå®è¡ããã¹ã¬ããã®æ°ã¯ããã·ã³ã®ã³ã¢ã®æ°ã«äŸåããŸããã¯ã©ã¹-PierLoaderãœãŒã¹ã³ãŒã public class PierLoader implements Runnable { private Tunnel tunnel; private Type shipType; public PierLoader(Tunnel tunnel, Type shipType) { this.tunnel = tunnel; this.shipType =shipType; } @Override public void run() { while (true) { try { Thread.currentThread().setName("Loader "+shipType);
è¹ãçæããããã³ãã«ã«è¿œå ãããŸããããã³ãã«ããè¹ãåãå€ããååãç©ãå¿
èŠããããŸãã ãããè¡ãããã«ãPierLoaderã¯ã©ã¹ãã€ãŸãæ¡æ©ãäœæããŸãã ãåç¥ã®ããã«ã3çš®é¡ã®è¹ããããããäºãã«ç¬ç«ããŠåäœãã3çš®é¡ã®ä¿çãäœæããå¿
èŠããããŸãã ShipGeneratorãšã®é¡æšã«ãããRunnableã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããŸãã å
¥å2ã®ãã©ã¡ãŒã¿ãŒã¯ããã³ãã«ãšã¿ã€ãïŒããŒã¹ããŒã¿ãåä¿¡ããè¹ã®ã¿ã€ãïŒã§ãã addïŒïŒã®ä»£ããã«ãgetïŒïŒã¡ãœãããšç¹å®ã®ã¿ã€ãã®ããŒããåŒã³åºããŸãã
sleepïŒïŒã¯ãããŒããŒã®äœæ¥ããšãã¥ã¬ãŒãããè¹ãçæããããã«ã®ã¿äœ¿çšããŸãïŒååã®ç©ã¿èŸŒã¿ã«æéãããããè¹ã¯èªè¡ããªããã°ãªããŸããïŒãä»ã®ãããŒã«åãããããã«é
延ããããã§ã¯ãããŸããã ããã絶察ã«è¡ããªãã§ãã ãããããã«ã¯å€ãã®çç±ããããŸããæãæçœãªã®ã¯ãã¹ããªãŒã Aã®è² è·ãå¢å ããã¹ããªãŒã BãïŒ1ç§éïŒå®æ¥œæ»ãããå Žåãããã¯ããã«é·ãïŒ1ç§ã§ã¯ãªã3ç§ïŒåäœãããšã©ããªããã§ããã¹ããªãŒã AãåŸ
ã¡ãŸããïŒ OSã«ãã£ãŠããJVMã®åäœã¯ç°ãªããŸãã ãåç¥ã®ããã«ãsleepã¯ãªãœãŒã¹ã解æŸããŸããããwaitïŒïŒã§ã¯ãªããã¹ãªãŒãäžããªãœãŒã¹ãä¿æããŸããããã«ãããã¹ã¬ããã¯åäœãåæ¢ããããã¯ã解é€ããŸããã¯ã©ã¹-ã¡ã€ã³ãœãŒã¹ã³ãŒã public class Main { public static void main(String[] args) { System.out.println("Available number of cores: " + Runtime.getRuntime().availableProcessors()); Tunnel tunnel = new Tunnel(); ShipGenerator shipGenerator = new ShipGenerator(tunnel, 10); PierLoader pierLoader1 = new PierLoader(tunnel, Type.DRESS); PierLoader pierLoader2 = new PierLoader(tunnel, Type.BANANA); PierLoader pierLoader3 = new PierLoader(tunnel, Type.MEAL); ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); service.execute(shipGenerator); service.execute(pierLoader1); service.execute(pierLoader2); service.execute(pierLoader3); service.shutdown(); } }
圌ãäžçªç°¡åã§ãã äœæããTunnelã¯ã©ã¹ãåæåããŸãã 次ã«ãShipGeneratorãåæåããŸããã³ã³ã¹ãã©ã¯ã¿ãŒã§ããã³ãã«ãªããžã§ã¯ããšããããŒã®çæã«å¿
èŠãªè¹ã®æ°ãæž¡ããŸãã
åæ§ã«ã3çš®é¡ã®è¹ãèªã¿èŸŒãããã®3ã€ã®PierLoaderãªããžã§ã¯ããäœæããŸãã TunnelãšåŒã°ããã¹ã¬ããã®å
±éãªãœãŒã¹ããã¶ã€ããŒã«æž¡ããŸãã ãããŠãè¹ã®çš®é¡PierLoaderãããŸãããã¯ãã§ãã
次ã«ãããããã¹ãŠãExecutorServiceã¯ã©ã¹ã«æž¡ããŸãã æåã«ãã¿ã¹ã¯ãå®è¡ããã¹ã¬ããã®ããŒã«ãäœæããŸãã Runtime.getRuntimeïŒïŒãAvailableProcessorsïŒïŒã³ãã³ãã䜿çšããŠã¹ã¬ããã®æ°ã決å®ããŸãã 䜿çšå¯èœãªã¹ããªãŒã ã®æ°ãint圢åŒã§è¿ããŸãã 䜿çšå¯èœãªã³ã¢ã8ã€ãããªãå Žåã1000åã®ã¹ã¬ãããäœæããŠãæå³ããããŸããã
ããŠãããã ãã§ãïŒ ãã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®æºåãã§ããŸããã ãããŒã®ã¿ã¹ã¯ã®æ°ãããŒãã®çææéãããã³ååã®ç©ã¿èŸŒã¿ããããããšãã§ããŸãã çµæã¯åžžã«ç°ãªããŸãã
ãããã«
çµè«ãšããŠããã«ãŒã¹ã»ãšãã±ã«ã®èæžãJava Philosophyããèªãããšããå§ãããŸãã ã䞊åå®è¡ãããã³ãJAVAãã®ç« ã ããã°ã©ãã³ã°æ¹æ³â N. Blinovaã ãã¹ããªãŒãã³ã°å®è¡ãã®ç« ã Javaã§ãã«ãã¹ã¬ããã䜿çšããåºæ¬çãªãã©ã¯ãã£ã¹ãšãã®è€éãã«ã€ããŠèª¬æããŸãã
ãã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ãäœæããåã«ãçŽã«ã¢ããªã±ãŒã·ã§ã³ãæç»ãããããžã§ã¯ãã®ã¹ã±ãããäœæããå¿
èŠããããŸãã å
±æãªãœãŒã¹ãé¿ããŠãã ããã å
±æãªãœãŒã¹ã¯æªã§ãã ãããŒããäºãããŸã£ããç¥ããããŸã£ããèããŠããªãæ¹ãè¯ãã§ãã ç¬èªã®ãã³ã§ãã¹ãŠãè¡ãããããæ¢è£œã®APIã䜿çšããŠãã ããã ããã«ãããéçºæéãççž®ãããã¢ããªã±ãŒã·ã§ã³ã®ä¿¡é Œæ§ãåäžããŸãã ã¢ããªã±ãŒã·ã§ã³ããã¹ãããã³ãããã¡ã€ã«ããŸãã ãããããã¢ããªã±ãŒã·ã§ã³ã®é床ãäœäžããããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®å¯èœæ§ãå®å
šã«ã¯æããã«ããªãä»ã®ããã«ããã¯ãèŠã€ããã§ãããã