• <dd id="wpirm"><center id="wpirm"></center></dd>

      <button id="wpirm"><acronym id="wpirm"></acronym></button>
      <s id="wpirm"><acronym id="wpirm"></acronym></s>

      好程序員-千鋒教育旗下高端IT職業教育品牌

      400-811-9990
      我的賬戶
      好程序員

      專注高端IT職業培訓

      親愛的猿猿,歡迎!

      已有賬號,請

      如尚未注冊?

      [BigData] 好程序員面試題分享同一資源多線程并發訪問時的完整性

      [復制鏈接]
      187 0
      葉子老師 發表于 2019-9-29 14:46:35 | 只看該作者 |閱讀模式 打印 上一主題 下一主題
        好程序員面試題分享同一資源多線程并發訪問時的完整性常用的同步方法是采用信號或加鎖機制,確保資源在任意時刻至多被一個線程訪問。Java語言在多線程編程上實現了完全對象化,提供了對同步機制的良好支持。
        在Java中一共有四種方法支持同步,其中前三個是同步方法,一個是管道方法。管道方法不建議使用,阻塞隊列方法在問題4已有描述,現只提供前兩種實現方法。
        - wait()/notify()方法
        - await()/signal()方法
        - BlockingQueue阻塞隊列方法
        - PipedInputStream/PipedOutputStream
        一、生產者類:
        ```
        public class Producer extends Thread { // 每次生產的產品數量
        private int num;
        // 所在放置的倉庫
        private Storage storage;
        // 構造函數,設置倉庫
        public Producer(Storage storage) {
        this.storage = storage;
        }
        // 線程run函數
        public void run() {
        produce(num);
        }
        // 調用倉庫Storage的生產函數
        public void produce(int num) {
        storage.produce(num);
        }
        public int getNum() {
        return num;
        }
        public void setNum(int num) {
        this.num = num;
        }
        public Storage getStorage() {
        return storage;
        }
        public void setStorage(Storage storage) {
        this.storage = storage;
        }
        }
        ```
        二、消費者類:
        ```
        public class Consumer extends Thread { // 每次消費的產品數量
        private int num;
        // 所在放置的倉庫
        private Storage storage;
        // 構造函數,設置倉庫
        public Consumer(Storage storage) {
        this.storage = storage;
        }
        // 線程run函數
        public void run() {
        consume(num);
        }
        // 調用倉庫Storage的生產函數
        public void consume(int num) {
        storage.consume(num);
        }
        // get/set方法
        public int getNum() {
        return num;
        }
        public void setNum(int num) {
        this.num = num;
        }
        public Storage getStorage() {
        return storage;
        }
        public void setStorage(Storage storage) {
        this.storage = storage;
        }
        }
        ```
        倉庫類:(wait()/notify()方法)
        ```
        public class Storage { // 倉庫最大存儲量
        private final int MAX_SIZE = 100;
        // 倉庫存儲的載體
        private LinkedList list = new LinkedList();
        // 生產num個產品
        public void produce(int num) {
        // 同步代碼段
        synchronized (list) {
        // 如果倉庫剩余容量不足
        while (list.size() + num > MAX_SIZE) {
        System.out.print("【要生產的產品數量】:" + num);
        System.out.println(" 【庫存量】:" + list.size() + " 暫時不能執行生產任務!");
        try {
        list.wait();// 由于條件不滿足,生產阻塞
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
        // 生產條件滿足情況下,生產num個產品
        for (int i = 1; i <= num; ++i) {
        list.add(new Object());
        }
        System.out.print("【已經生產產品數】:" + num);
        System.out.println(" 【現倉儲量為】:" + list.size());
        list.notifyAll();
        }
        }
        // 消費num個產品
        public void consume(int num) {
        // 同步代碼段
        synchronized (list) {
        // 如果倉庫存儲量不足
        while (list.size() < num) {
        System.out.print("【要消費的產品數量】:" + num);
        System.out.println(" 【庫存量】:" + list.size() + " 暫時不能執行生產任務!");
        try {
        // 由于條件不滿足,消費阻塞
        list.wait();
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
        // 消費條件滿足情況下,消費num個產品
        for (int i = 1; i <= num; ++i) {
        list.remove();
        }
        System.out.print("【已經消費產品數】:" + num);
        System.out.println(" 【現倉儲)量為】:" + list.size());
        list.notifyAll();
        }
        }
        // get/set方法
        public LinkedList getList() {
        return list;
        }
        public void setList(LinkedList list) {
        this.list = list;
        }
        public int getMAX_SIZE() {
        return MAX_SIZE;
        }
        }
        ```
        倉庫類:(await()/signal()方法)
        ```
        public class Storage { // 倉庫最大存儲量
        // 倉庫最大存儲量
        private final int MAX_SIZE = 100;
        // 倉庫存儲的載體
        private LinkedList list = new LinkedList();
        //
        private final Lock lock = new ReentrantLock();
        // 倉庫滿的條件變量
        private final Condition full = lock.newCondition();
        // 倉庫空的條件變量
        private final Condition empty = lock.newCondition();
        // 生產num個產品
        public void produce(int num) {
        // 獲得鎖
        lock.lock();
        // 如果倉庫剩余容量不足
        while (list.size() + num > MAX_SIZE) {
        System.out.print("【要生產的產品數量】:" + num);
        System.out.println(" 【庫存量】:" + list.size() + " 暫時不能執行生產任務!");
        try {
        // 由于條件不滿足,生產阻塞
        full.await();
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
        // 生產條件滿足情況下,生產num個產品
        for (int i = 1; i <= num; ++i) {
        list.add(new Object());
        }
        System.out.print("【已經生產產品數】:" + num);
        System.out.println(" 【現倉儲量為】:" + list.size());
        // 喚醒其他所有線程
        full.signalAll();
        empty.signalAll();
        // 釋放鎖
        lock.unlock();
        }
        // 消費num個產品
        public void consume(int num) {
        // 獲得鎖
        lock.lock();
        // 如果倉庫存儲量不足
        while (list.size() < num) {
        System.out.print("【要消費的產品數量】:" + num);
        System.out.println(" 【庫存量】:" + list.size() + " 暫時不能執行生產任務!");
        try {
        // 由于條件不滿足,消費阻塞
        empty.await();
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        }
        // 消費條件滿足情況下,消費num個產品
        for (int i = 1; i <= num; ++i) {
        list.remove();
        }
        System.out.print("【已經消費產品數】:" + num);
        System.out.println(" 【現倉儲)量為】:" + list.size());
        // 喚醒其他所有線程
        full.signalAll();
        empty.signalAll();
        // 釋放鎖
        lock.unlock();
        }
        // set/get方法
        public int getMAX_SIZE() {
        return MAX_SIZE;
        }
        public LinkedList getList() {
        return list;
        }
        public void setList(LinkedList list) {
        this.list = list;
        }
        }

      精彩內容,一鍵分享給更多人!
      收藏
      收藏0
      轉播
      轉播
      分享
      淘帖0
      支持
      支持0
      反對
      反對0
      回復

      使用道具 舉報

      您需要登錄后才可以回帖

      本版積分規則

      關注我們
      好程序員
      千鋒好程序員

      北京校區(總部):北京市海淀區寶盛北里西區28號中關村智誠科創大廈

      深圳西部硅谷校區:深圳市寶安區寶安大道5010號深圳西部硅谷B座A區605-619

      杭州龍馳智慧谷校區:浙江省杭州市下沙經濟技術開發區元成路199號龍馳智慧谷B座7層

      鄭州校區:鄭州市二七區航海中路60號海為科技園C區10層、12層

      Copyright 2007-2019 北京千鋒互聯科技有限公司 .All Right

      京ICP備12003911號-5 京公安網11010802011455號

      請您保持通訊暢通1對1咨詢馬上開啟

      Pictoa