02.第二階段、實戰Java高併發程序設計模式-6.併發設計模式

1、併發設計模式java

 什麼是設計模式 
 單例模式
 不變模式
 Future模式
 生產者消費者
  1. 什麼是設計模式設計模式

    在軟件工程中,設計模式(design pattern)是對軟件設計中廣泛存在(反覆出現)的各類問題 ,所提出的解決方案。這個術語是由埃裏希·伽瑪(Erich Gamma)等人在1990年代從建築設計領 域引入到計算機科學的。
      Richard Helm, Ralph Johnson ,John Vlissides (Gof)
      《設計模式:可複用面向對象軟件的基礎》 收錄 23種模式
    
      – 觀察者模式
      – 策略模式
      – 裝飾者模式 – 享元模式
      – 模板方法
    
      架構模式 – MVC
     – 分層 
      設計模式
     – 提煉系統中的組件
      代碼模式(成例 Idiom)
     – 低層次,與編碼直接相關 – 如DCL
  2. 單例模式安全

    單例對象的類必須保證只有一個實例存在。許多時候整個系統只須要擁有一個的全局對象,這樣 有利於咱們協調系統總體的行爲
     好比:全局信息配置
    /**
    	 * description: 餓漢式 線程安全
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    7:32 PM
    	 */
    	public class Singleton {
    		public static int STATUS = 1;
    
    		private Singleton() {
    			System.out.println("Singleton is create");
    		}
    
    		private static Singleton instance = new Singleton();
    
    		public static Singleton getInstance() {
    			return instance;
    		}
    
    		public static void main(String[] args) {
    			//什麼時候產生實例 很差控制
    			System.out.println(Singleton.STATUS);
    			//輸出
    			// Singleton is create
    			//1
    		}
    
    
    	}
    /**
    	 * description: 懶漢式 線程安全
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    7:37 PM
    	 */
    	public class LazySingleton {
    		//1.
    		private LazySingleton() {
    			System.out.println("LazySingleton is create");
    		}
    
    		private static LazySingleton instance = null;
    
    		public static synchronized LazySingleton getInstance() {
    			if (instance == null)
    				instance = new LazySingleton();
    			return instance;
    
    		}
    
    	//      2. 多線程 性能好
    	//    雙檢鎖/雙重校驗鎖(DCL,即 double-checked locking)線程安全
    	//    private volatile static LazySingleton instance;
    	//    private LazySingleton (){
    	//        System.out.println("LazySingleton is create");
    	//    }
    	//    public static LazySingleton getInstance() {
    	//        if (instance == null) {
    	//            synchronized (LazySingleton.class) {
    	//                if (instance == null) {
    	//                    instance = new LazySingleton();
    	//                }
    	//            }
    	//        }
    	//        return instance;
    	//    }
    
    		public static void main(String[] args) {
    			LazySingleton.getInstance();
    		}
    	}
    /**
    	 * description: 靜態內部類 線程安全
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    7:39 PM
    	 */
    	public class StaticSingleton {
    		private StaticSingleton() {
    			System.out.println("StaticSingleton is create");
    		}
    
    		private static class SingletonHolder {
    			private static final StaticSingleton instance = new StaticSingleton();
    		}
    
    		public static final StaticSingleton getInstance() {
    			return SingletonHolder.instance;
    		}
    
    
    		public static void main(String[] args) {
    			StaticSingleton.getInstance();
    		}
    	}
  3. 不變模式多線程

     一個類的內部狀態建立後,在整個生命期間都不會發生變化時,就是不變類 
      不變模式不須要同步
    /**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    7:55 PM
    	 */
    	//確保無子類
    	public final class Product {
    		private final String no;
    		//私有屬性,不會被其餘對象獲取
    		private final String name;
    		//final保證屬性不會被2次賦值
    		private final double price;
    
    		public Product(String no, String name, double price) {
    			super();
    			//由於建立以後,沒法進行修改
    			this.no = no;
    			this.name = name;
    			this.price = price;
    		}
    
    		public String getNo() {
    			return no;
    		}
    
    		public String getName() {
    			return name;
    		}
    
    		public double getPrice() {
    			//在建立對象時,必須指定數據
    			return price;
    		}
    
    	}
     java.lang.String
      java.lang.Boolean 
      java.lang.Byte
      java.lang.Character 
      java.lang.Double
      java.lang.Float
      java.lang.Integer
      java.lang.Long
      java.lang.Short
  4. Future模式架構

    /**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    8:07 PM
    	 */
    	public class RealData implements Data {
    		protected final String result;
    
    		public RealData(String para) {
    			//RealData的構造可能很慢,須要用戶等待好久,這裏使用sleep模擬
    			StringBuffer sb = new StringBuffer();
    			for (int i = 0; i < 10; i++) {
    				sb.append(para);
    				try {
    					//這裏使用sleep,代替一個很慢的操做過程
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    				}
    			}
    			result = sb.toString();
    		}
    
    		public String getResult() {
    			return result;
    		}
    	}
    /**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    8:05 PM
    	 */
    	public class FutureData implements Data {
    		//FutureData是RealData的包裝
    
    		protected RealData realdata = null;
    		protected boolean isReady = false;
    
    		public synchronized void setRealData(RealData realdata) {
    			if (isReady) {
    				return;
    			}
    			this.realdata = realdata;
    			isReady = true;
    			//RealData已經被注入,通知getResult()
    			notifyAll();
    		}
    
    		//會等待RealData構造完成
    		public synchronized String getResult() {
    			while (!isReady) {
    				try {
    					//一直等待,知道RealData被注入
    
    					wait();
    				} catch (InterruptedException e) {
    				}
    			}
    			//由RealData實現
    			return realdata.result;
    		}
    	}
    /**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    8:07 PM
    	 */
    	public class Client {
    		public Data request(final String queryStr) {
    			final FutureData future = new FutureData();
    			new Thread() {
    				// RealData的構建很慢,因此在單獨的線程中進行
    				public void run() {
    					RealData realdata = new RealData(queryStr);
    					future.setRealData(realdata);
    				}
    			}.start();
    			// FutureData會被當即返回
    			return future;
    		}
    
    		public static void main(String[] args) {
    
    			Client client = new Client();
    			//這裏會當即返回,由於獲得的是FutureData而不是RealData
    			Data data = client.request("name");
    			System.out.println("請求完畢");
    			try {
    			//這裏能夠用一個sleep代替了對其餘業務邏輯的處理
    			//在處理這些業務邏輯的過程當中,RealData被建立,從而充分利用了等待時間
    				Thread.sleep(2000);
    			} catch (InterruptedException e) {
    			}
    			//使用真實的數據
    			System.out.println("數據 = " + data.getResult());
    		}
    	}

    Callable 接口併發

    import java.util.concurrent.Callable;
    
    	/**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    8:07 PM
    	 */
    	public class RealData implements Callable<String> {
    		protected final String para;
    
    		public RealData(String para) {
    
    			this.para = para;
    		}
    
    		@Override
    		public String call() throws Exception {
    			//RealData的構造可能很慢,須要用戶等待好久,這裏使用sleep模擬
    			StringBuffer sb = new StringBuffer();
    			for (int i = 0; i < 10; i++) {
    				sb.append(para);
    				try {
    					//這裏使用sleep,代替一個很慢的操做過程
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    				}
    			}
    			return sb.toString();
    		}
    	}
    import java.util.concurrent.ExecutionException;
    	import java.util.concurrent.ExecutorService;
    	import java.util.concurrent.Executors;
    	import java.util.concurrent.Future;
    	import java.util.concurrent.FutureTask;
    
    	/**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    8:27 PM
    	 */
    	public class FutureMain {
    		public static void main(String[] args) throws InterruptedException, ExecutionException {
    			//1.
    	//        //構造FutureTask
    	//        FutureTask<String> future = new FutureTask<String>(new RealData("a"));
    	//        ExecutorService executor = Executors.newFixedThreadPool(1);
    	//        //執行FutureTask,至關於上例中的 client.request("a") 發送請求
    	//        // 在這裏開啓線程進行RealData的call()執行
    	//        executor.submit(future);
    	//        executor.shutdown();
    	//        System.out.println("請求完畢");
    	//        try {
    	//            //這裏依然能夠作額外的數據操做,這裏使用sleep代替其餘業務邏輯的處理
    	//            Thread.sleep(2000);
    	//        } catch (InterruptedException e) {
    	//        }
    	//        //至關於data.getResult (),取得call()方法的返回值
    	//        // 若是此時call()方法沒有執行完成,則依然會等待
    	//        System.out.println("數據 = " + future.get());
    
    			//2.
    			ExecutorService executor = Executors.newFixedThreadPool(1);
    			//執行FutureTask,至關於上例中的 client.request("a") 發送請求
    			// 在這裏開啓線程進行RealData的call()執行
    			Future<String> future = executor.submit(new RealData("a"));
    			System.out.println("請求完畢");
    			try { //這裏依然能夠作額外的數據操做,這裏使用sleep代替其餘業務邏輯的處理
    				Thread.sleep(2000);
    			} catch (InterruptedException e) {
    			}
    			//至關於data.getResult (),取得call()方法的返回值
    			// 若是此時call()方法沒有執行完成,則依然會等待
    			System.out.println("數據 = " + future.get());
    		}
    
    	}
  5. 生產者消費者模式app

    生產者-消費者模式是一個經典的多線程設計模式。它爲多線程間的協做提供了良好的解決方案。 在生產者-消費者模式中,一般由兩類線程,即若干個生產者線程和若干個消費者線程。生產者線 程負責提交用戶請求,消費者線程則負責具體處理生產者提交的任務。生產者和消費者之間則通 過共享內存緩衝區進行通訊。

    /**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    10:32 PM
    	 */
    	public final class PCData {
    		private final int intData;
    
    		public PCData(int intData) {
    			this.intData = intData;
    		}
    
    		public PCData(String d) {
    			this.intData = Integer.valueOf(d);
    		}
    
    		public int getIntData() {
    			return intData;
    		}
    
    		@Override
    		public String toString() {
    			return "data:" + intData;
    		}
    	}
    import java.util.Random;
    	import java.util.concurrent.BlockingQueue;
    	import java.util.concurrent.TimeUnit;
    	import java.util.concurrent.atomic.AtomicInteger;
    
    	/**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/3    10:05 PM
    	 */
    	public class Producer implements Runnable{
    
    		private volatile boolean isRunning = true;
    		private BlockingQueue<PCData> queue;
    		private static AtomicInteger count = new AtomicInteger();
    		private static final int SLEEPTIME = 1000;
    
    		public Producer(BlockingQueue<PCData> queue) {
    			this.queue = queue;
    		}
    
    		@Override
    		public void run() {
    			PCData data = null;
    			Random r = new Random();
    			System.out.println("start producer id=" + Thread.currentThread().getId());
    			try {
    				while (isRunning) {
    					Thread.sleep(r.nextInt(SLEEPTIME));
    					data = new PCData(count.incrementAndGet());
    					System.out.println(data + " is put into queue");
    					if (!queue.offer(data,2, TimeUnit.SECONDS)) {
    						System.out.println("failed to put data: " + data);
    					}
    				}
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    				Thread.currentThread().interrupt();
    			}
    		}
    		public void stop() {
    			isRunning = false;
    		}
    	}
    import java.text.MessageFormat;
    	import java.util.Random;
    	import java.util.concurrent.BlockingQueue;
    
    	/**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/3    10:05 PM
    	 */
    	public class Consumer implements Runnable{
    
    		private BlockingQueue<PCData> queue;
    		private static final int SLEEPTIME = 1000;
    
    		public Consumer(BlockingQueue<PCData> queue) {
    			this.queue = queue;
    		}
    
    		@Override
    		public void run() {
    			System.out.println("start Consumer id=" + Thread.currentThread().getId());
    			Random r = new Random();
    			try {
    				while (true) {
    					PCData data = queue.take();
    					if (null != data) {
    						int re = data.getIntData() * data.getIntData();
    						System.out.println(MessageFormat.format("{0}*{1}={2}",data.getIntData(),data.getIntData(),re));
    						Thread.sleep(r.nextInt(SLEEPTIME));
    					}
    				}
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    				Thread.currentThread().interrupt();
    			}
    		}
    	}
    /**
    	 * description:
    	 *
    	 * @author: dawn.he QQ:       905845006
    	 * @email: dawn.he@cloudwise.com
    	 * @email: 905845006@qq.com
    	 * @date: 2019/10/4    10:19 PM
    	 */
    	import java.util.concurrent.BlockingQueue;
    	import java.util.concurrent.ExecutorService;
    	import java.util.concurrent.Executors;
    	import java.util.concurrent.LinkedBlockingQueue;
    
    	public class Storage {
    
    		// 倉庫存儲的載體
    		private LinkedBlockingQueue<Object> list = new LinkedBlockingQueue<>(10);
    
    		public void produce() {
    			try{
    				list.put(new Object());
    				System.out.println("【生產者" + Thread.currentThread().getName()
    						+ "】生產一個產品,現庫存" + list.size());
    			} catch (InterruptedException e){
    				e.printStackTrace();
    			}
    		}
    
    		public void consume() {
    			try{
    				list.take();
    				System.out.println("【消費者" + Thread.currentThread().getName()
    						+ "】消費了一個產品,現庫存" + list.size());
    			} catch (InterruptedException e){
    				e.printStackTrace();
    			}
    		}
    
    		public static void main(String[] args) throws InterruptedException {
    	//       Storage storage =  new Storage();
    	//        storage.produce();
    	//        storage.consume();
    
    				BlockingQueue<PCData> queue = new LinkedBlockingQueue<>(10);
    				Producer producer1 = new Producer(queue);
    				Producer producer2 = new Producer(queue);
    				Producer producer3 = new Producer(queue);
    				Consumer consumer1 = new Consumer(queue);
    				Consumer consumer2 = new Consumer(queue);
    				Consumer consumer3 = new Consumer(queue);
    				ExecutorService service = Executors.newCachedThreadPool();
    				service.execute(producer1);
    				service.execute(producer2);
    				service.execute(producer3);
    				service.execute(consumer1);
    				service.execute(consumer2);
    				service.execute(consumer3);
    				Thread.sleep(10 * 1000);
    				producer1.stop();
    				producer2.stop();
    				producer3.stop();
    				Thread.sleep(3000);
    				service.shutdown();
    		}
    	}

從BlockingQueue到無鎖Disruptor的性能提高:https://blog.csdn.net/weixin_33704591/article/details/92407717dom

相關文章
相關標籤/搜索