最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java生產(chǎn)者消費者的三種實現(xiàn)方式

 更新時間:2024年07月04日 10:39:34   作者:xindoo  
這篇文章主要介紹了Java生產(chǎn)者消費者的三種實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Java生產(chǎn)者消費者的實現(xiàn)

Java生產(chǎn)者消費者是最基礎的線程同步問題,java崗面試中還是很容易遇到的,之前沒寫過多線程的代碼,面試中被問到很尬啊,面完回來惡補下。

在網(wǎng)上查到大概有5種生產(chǎn)者消費者的寫法,分別如下。

  • 用synchronized對存儲加鎖,然后用object原生的wait() 和 notify()做同步。
  • 用concurrent.locks.Lock,然后用condition的await() 和signal()做同步。
  • 直接使用concurrent.BlockingQueue。
  • 使用PipedInputStream/PipedOutputStream。
  • 使用信號量semaphore。  

我的理解,生產(chǎn)者消費者模式,其實只要保證在存儲端同一時刻只有一個線程讀或?qū)懢筒粫袉栴},然后再去考慮線程同步。

方法1 2 5都比較類似,都是加鎖來限制同一時刻只能有一個讀或?qū)?。而方? 4其實是在存儲內(nèi)部去保證讀和寫的唯一的,最低層肯定還是通過鎖機制來實現(xiàn)的,java底層代碼都封裝好了而已?! ?/p>

我自己嘗試寫了下前三種,代碼如下: 

synchronized版本

import java.util.LinkedList;
import java.util.Queue;

public class ProducerAndConsumer {
    private final int MAX_LEN = 10;
    private Queue<Integer> queue = new LinkedList<Integer>();
    class Producer extends Thread {
        @Override
        public void run() {
            producer();
        }
        private void producer() {
            while(true) {
                synchronized (queue) {
                    while (queue.size() == MAX_LEN) {
                        queue.notify();
                        System.out.println("當前隊列滿");
                        try {
                            queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.add(1);
                    queue.notify();
                    System.out.println("生產(chǎn)者生產(chǎn)一條任務,當前隊列長度為" + queue.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    class Consumer extends Thread {
        @Override
        public void run() {
            consumer();
        }
        private void consumer() {
            while (true) {
                synchronized (queue) {
                    while (queue.size() == 0) {
                        queue.notify();
                        System.out.println("當前隊列為空");
                        try {
                            queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.poll();
                    queue.notify();
                    System.out.println("消費者消費一條任務,當前隊列長度為" + queue.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    public static void main(String[] args) {
        ProducerAndConsumer pc = new ProducerAndConsumer();
        Producer producer = pc.new Producer();
        Consumer consumer = pc.new Consumer();
        producer.start();
        consumer.start();
    }
}

lock版實現(xiàn),使用了condition做線程之間的同步

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * version 1 doesn't use synchronized to improve performance
 */
public class ProducerAndConsumer1 {
    private final int MAX_LEN = 10;
    private Queue<Integer> queue = new LinkedList<Integer>();
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    class Producer extends Thread {
        @Override
        public void run() {
            producer();
        }
        private void producer() {
            while(true) {
                lock.lock();
                try {
                    while (queue.size() == MAX_LEN) {
                        System.out.println("當前隊列滿");
                        try {
                            condition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.add(1);
                    condition.signal();
                    System.out.println("生產(chǎn)者生產(chǎn)一條任務,當前隊列長度為" + queue.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } finally {
                    lock.unlock();
                }
            }
        }
    }
    class Consumer extends Thread {
        @Override
        public void run() {
            consumer();
        }
        private void consumer() {
            while (true) {
                lock.lock();
                try {
                    while (queue.size() == 0) {
                        System.out.println("當前隊列為空");
                        try {
                            condition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.poll();
                    condition.signal();
                    System.out.println("消費者消費一條任務,當前隊列長度為" + queue.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } finally {
                    lock.unlock();
                }
            }
        }
    }
    public static void main(String[] args) {
        ProducerAndConsumer pc = new ProducerAndConsumer();
        Producer producer = pc.new Producer();
        Consumer consumer = pc.new Consumer();
        producer.start();
        consumer.start();
    }
}

BlockingQueue版實現(xiàn)

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;


public class ProducerAndConsumer {
    private BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(10);
    class Producer extends Thread {
        @Override
        public void run() {
            producer();
        }
        private void producer() {
            while(true) {
                try {
                    queue.put(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("生產(chǎn)者生產(chǎn)一條任務,當前隊列長度為" + queue.size());
                try {
                    Thread.sleep(new Random().nextInt(1000)+500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    class Consumer extends Thread {
        @Override
        public void run() {
            consumer();
        }
        private void consumer() {
            while (true) {
                try {
                    queue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消費者消費一條任務,當前隊列長度為" + queue.size());
                try {
                    Thread.sleep(new Random().nextInt(1000)+500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        ProducerAndConsumer pc = new ProducerAndConsumer();
        Producer producer = pc.new Producer();
        Consumer consumer = pc.new Consumer();
        producer.start();
        consumer.start();
    }
}

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • SpringBoot實現(xiàn)隱式參數(shù)注入的完整指南

    SpringBoot實現(xiàn)隱式參數(shù)注入的完整指南

    這篇文章主要為大家詳細介紹了SpringBoot實現(xiàn)隱式參數(shù)注入的相關方法,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-11-11
  • Mybatis批量插入返回插入成功后的主鍵id操作

    Mybatis批量插入返回插入成功后的主鍵id操作

    這篇文章主要介紹了Mybatis批量插入返回插入成功后的主鍵id操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Java異常處理方法匯總

    Java異常處理方法匯總

    這篇文章主要介紹了Java異常處理方法匯總,我們在軟件開發(fā)的過程中,任何語言的開發(fā)過程中都離不開異常處理。下面下小編加來給大家分享各種異常處理,希望對大家有所幫助,需要的朋友可以參考一下
    2021-12-12
  • 使用Javacsv.jar的jar包操作csv文件的方法

    使用Javacsv.jar的jar包操作csv文件的方法

    使用javacsv的jar包很方便的可以操作csv文件。下面通過本教程給大家介紹使用javacsv.jar操作csv文件的方法,感興趣的朋友一起看下吧
    2016-08-08
  • Spring Cloud體系實現(xiàn)標簽路由的方法示例

    Spring Cloud體系實現(xiàn)標簽路由的方法示例

    這篇文章主要介紹了Spring Cloud體系實現(xiàn)標簽路由的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • 通過原理解析Spring mvc的內(nèi)置編碼過濾器

    通過原理解析Spring mvc的內(nèi)置編碼過濾器

    這篇文章通過原理主要給大家解析了關于Spring mvc的內(nèi)置編碼過濾器的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2017-09-09
  • MyBatis動態(tài)SQL foreach標簽實現(xiàn)批量插入的方法示例

    MyBatis動態(tài)SQL foreach標簽實現(xiàn)批量插入的方法示例

    這篇文章主要介紹了MyBatis動態(tài)SQL foreach標簽實現(xiàn)批量插入的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • java如何根據(jù)HttpServletRequest獲取IP地址

    java如何根據(jù)HttpServletRequest獲取IP地址

    文章介紹了幾種代理服務器轉(zhuǎn)發(fā)服務請求頭的方法,這些請求頭可能包含真實IP地址,但并不是所有的代理都會包括這些請求頭,而且這些IP地址可能被偽造
    2025-03-03
  • Java中的Semaphore信號量詳解

    Java中的Semaphore信號量詳解

    這篇文章主要介紹了Java中的Semaphore信號量詳解,Semaphore(信號量)是用來控制同時訪問特定資源的線程數(shù)量,通過協(xié)調(diào)各個線程以保證合理地使用公共資源,需要的朋友可以參考下
    2023-12-12
  • Java gRPC攔截器簡單實現(xiàn)分布式日志鏈路追蹤器過程詳解

    Java gRPC攔截器簡單實現(xiàn)分布式日志鏈路追蹤器過程詳解

    有請求的發(fā)送、處理,當然就會有攔截器的需求,例如在服務端通過攔截器統(tǒng)一進行請求認證等操作,這些就需要攔截器來完成,今天松哥先和小伙伴們來聊一聊gRPC中攔截器的基本用法,后面我再整一篇文章和小伙伴們做一個基于攔截器實現(xiàn)的JWT認證的gRPC
    2023-03-03

最新評論

汝南县| 宁阳县| 石渠县| 昌邑市| 锦州市| 无锡市| 沈丘县| 大姚县| 梨树县| 南宫市| 芜湖县| 阳山县| 磐安县| 如东县| 政和县| 曲阳县| 清河县| 锡林郭勒盟| 桐庐县| 崇信县| 衡山县| 镇赉县| 凤翔县| 余庆县| 阳新县| 双鸭山市| 武城县| 黄骅市| 湖南省| 交口县| 饶平县| 彰武县| 仙游县| 城固县| 会宁县| 霍城县| 呼伦贝尔市| 永德县| 葵青区| 维西| 扎鲁特旗|