需求:三我的賣30張票java
代碼:併發
package com.lee.juc.concurrent; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class SaleTicket { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(new Runnable() { public void run() { for(int i=0;i<100;i++) { ticket.sale(); } } },"AA").start(); new Thread(new Runnable() { public void run() { for(int i=0;i<100;i++) { ticket.sale(); } } },"BB").start(); new Thread(new Runnable() { public void run() { for(int i=0;i<100;i++) { ticket.sale(); } } },"CC").start(); } } //票 class Ticket{ private int num=30; private Lock lock = new ReentrantLock(); public void sale() { lock.lock(); try { if(num>0) { System.out.println(Thread.currentThread().getName()+".....sale ticket number : "+num--); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
用lambda寫:dom
package com.lee.juc.concurrent; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class SaleTicket { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(()->{for(int i=0;i<100;i++) {ticket.sale();}},"AA").start(); new Thread(()->{for(int i=0;i<100;i++) {ticket.sale();}},"BB").start(); new Thread(()->{for(int i=0;i<100;i++) {ticket.sale();}},"CC").start(); } } //票 class Ticket{ private int num=30; private Lock lock = new ReentrantLock(); public void sale() { lock.lock(); try { if(num>0) { System.out.println(Thread.currentThread().getName()+".....sale ticket number : "+num--); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
代碼:ui
package com.lee.juc.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 在主線程中須要執行比較耗時的操做,但又不想阻塞主線程時.能夠把這些對象交給Future對象在後臺執行,當主線程須要時, * 就能夠經過Future對象得到後臺做業計算的結果或者執行狀態. * * 通常FutureTask多用於耗時的計算,主線程能夠在完成本身的任務後,再去獲取結果. * * 僅在計算完成時才能檢索結果,若是計算還沒有完成,則阻塞get方法.一旦計算完成,就不能再從新開始或取消計算. * get方法獲取結果只有在計算完成時獲取,不然會一直阻塞到任務轉入完成狀態,而後會返回結果或者拋出異常. * */ public class CallableDemo { public static void main(String[] args) throws InterruptedException, ExecutionException { FutureTask<Integer> futureTak = new FutureTask<>(new MyThread()); new Thread(futureTak, "AA").start(); new Thread(futureTak, "BB").start(); System.out.println("...this is main method : "+Thread.currentThread().getName()); Integer aResult = futureTak.get(); System.out.println("A---->"+aResult); Integer bResult = futureTak.get(); System.out.println("B---->"+aResult); } } class MyThread implements Callable<Integer>{ public Integer call() throws Exception { System.out.println("this is...call...method : "+Thread.currentThread().getName()); Thread.sleep(3000); return 300; } }
代碼:this
package com.lee.juc.concurrent; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; public class ExecutorDemo { public static void main(String[] args) { ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5); ScheduledFuture<Integer> scheduledFuture = null; try { for (int i = 0; i < 10; i++) { scheduledFuture = scheduledExecutorService.schedule(()->{ System.out.print(Thread.currentThread().getName()+"..."); return new Random().nextInt(10); }, 2, TimeUnit.SECONDS); System.out.println("...."+scheduledFuture.get()); } } catch (Exception e) { e.printStackTrace(); }finally { scheduledExecutorService.shutdown(); } } private static void ExecutorService() { // ExecutorService executorService = Executors.newFixedThreadPool(5); // ExecutorService executorService = Executors.newSingleThreadExecutor(); ExecutorService executorService = Executors.newCachedThreadPool(); Future<Integer> future = null; try { for(int i=0;i<10;i++) { future = executorService.submit(()->{ System.out.print(Thread.currentThread().getName()+"..."); return new Random().nextInt(10); }); System.out.println("...."+future.get()); } } catch (Exception e) { e.printStackTrace(); } finally { executorService.shutdown(); } } }
代碼:spa
package com.lee.juc.concurrent; public enum CountryEnum { ONE(1,"韓"),TWO(2,"趙"),THREE(3,"燕"),FOUR(4,"魏"),FIVE(5,"楚"),SIX(6,"齊"); private Integer code; private String message; private CountryEnum(Integer code, String message) { this.code = code; this.message = message; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public static CountryEnum foreachCountryEnums(Integer index) { for(CountryEnum countryEnum : values()) { if(countryEnum.getCode() == index) { return countryEnum; } } return null; } } //================================================================= package com.lee.juc.concurrent; import java.util.concurrent.CountDownLatch; /** * 讓一些線程阻塞直到另外一些線程完成後,才被喚醒 * * 6國被滅後,秦才一統華夏 */ public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(6); for (int i = 1; i <= 6; i++) { new Thread(()->{ System.out.println(Thread.currentThread().getName()+"\t國被滅"); latch.countDown(); }, CountryEnum.foreachCountryEnums(i).getMessage()).start(); } latch.await(); System.out.println(Thread.currentThread().getName()+"....."+"秦滅六國,一統華夏"); } }
代碼:線程
package com.lee.juc.concurrent; import java.util.Random; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; /** * 在信號量上咱們定義兩種操做: * acquire(獲取),當一個線程調用acquire操做時,他要麼成功經過獲取信號量(信號量減1),要麼一直等下去,直到有線程釋放信號量,或超時. * release(釋放),實際上會將信號量的值加1,而後喚醒等待的線程. * * 信號量主要用於兩個目的: * 一個是用於共享資源的互斥. * 另外一個是用於併發線程的控制. * * eg:模擬6輛車,搶3個停車位. * */ public class SemaphoreDemo { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3);//模擬三個車位 for (int i = 0; i < 6; i++) { //模擬6輛車 try { new Thread(()->{ try { semaphore.acquire();//佔領車位 System.out.println(Thread.currentThread().getName()+" 佔領車位..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5));//佔領一段時間 System.out.println("...."+Thread.currentThread().getName()+"離開車位"); } catch (Exception e) { e.printStackTrace(); } finally { semaphore.release(); } }, String.valueOf(i)).start(); } catch (Exception e) { e.printStackTrace(); } finally { } } } }
代碼:code
package com.lee.juc.concurrent; import java.util.Random; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeUnit; /** * cyclic可循環的 barrier柵欄、屏障 * 讓一組線程達到屏障時(阻塞點)被阻塞,直到最後一個線程也達到了屏障時,屏障纔會打開,全部被屏障的線程纔會繼續幹活。 * * eg:集齊七顆龍珠,召喚神龍 */ public class CyclicBarrierDemo { private static final Integer NUMBER = 7; public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7, ()->{System.out.println("召喚神龍!");}); for (int i = 0; i < NUMBER; i++) { Integer temp = i; new Thread(()->{ try { TimeUnit.SECONDS.sleep(new Random().nextInt(5));//手機龍珠的過程 System.out.println(Thread.currentThread().getName()+"\t收集到第"+temp+"顆龍珠"); cyclicBarrier.await();//等着其餘龍珠被收集 } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } },String.valueOf(i)).start(); } } }