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

Java多線程 生產(chǎn)者消費(fèi)者模型實(shí)例詳解

 更新時(shí)間:2019年09月06日 09:17:01   作者:慢慢來  
這篇文章主要介紹了Java多線程 生產(chǎn)者消費(fèi)者模型實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

生產(chǎn)者消費(fèi)者模型

生產(chǎn)者:生產(chǎn)任務(wù)的個(gè)體;

消費(fèi)者:消費(fèi)任務(wù)的個(gè)體;

緩沖區(qū):是生產(chǎn)者和消費(fèi)者之間的媒介,對生產(chǎn)者和消費(fèi)者解耦。

當(dāng)

緩沖區(qū)元素為滿,生產(chǎn)者無法生產(chǎn),消費(fèi)者繼續(xù)消費(fèi);

緩沖區(qū)元素為空,消費(fèi)者無法消費(fèi),生產(chǎn)者繼續(xù)生產(chǎn);

wait()/notify()生產(chǎn)者消費(fèi)者模型

制作一個(gè)簡單的緩沖區(qū)ValueObject,value為空表示緩沖區(qū)為空,value不為空表示緩沖區(qū)滿

public class ValueObject {
  public static String value = "";
}

生產(chǎn)者,緩沖區(qū)滿則wait(),不再生產(chǎn),等待消費(fèi)者notify(),緩沖區(qū)為空則開始生產(chǎn)

public class Producer {
  private Object lock;

  public Producer(Object lock)
  {
    this.lock = lock;
  }

  public void setValue()
  {
    try
    {
      synchronized (lock)
      {
        if (!ValueObject.value.equals(""))
          lock.wait();
        String value = System.currentTimeMillis() + "_" + System.nanoTime();
        System.out.println("Set的值是:" + value);
        ValueObject.value = value;
        lock.notify();
      }
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
  }
}

消費(fèi)者,緩沖區(qū)為空則wait(),等待生產(chǎn)者notify(),緩沖區(qū)為滿,消費(fèi)者開始消費(fèi)

public class Customer {
  private Object lock;

  public Customer(Object lock)
  {
    this.lock = lock;
  }

  public void getValue()
  {
    try
    {
      synchronized (lock)
      {
        if (ValueObject.value.equals(""))
          lock.wait();
        System.out.println("Get的值是:" + ValueObject.value);
        ValueObject.value = "";
        lock.notify();
      }
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
  }
}

main方法,啟動(dòng)一個(gè)生產(chǎn)者和一個(gè)消費(fèi)者

public class Main {
  public static void main(String[] args)
  {
    Object lock = new Object();
    final Producer producer = new Producer(lock);
    final Customer customer = new Customer(lock);
    Runnable producerRunnable = new Runnable()
    {
      public void run()
      {
        while (true)
        {
          producer.setValue();
        }
      }
    };
    Runnable customerRunnable = new Runnable()
    {
      public void run()
      {
        while (true)
        {
          customer.getValue();
        }
      }
    };
    Thread producerThread = new Thread(producerRunnable);
    Thread CustomerThread = new Thread(customerRunnable);
    producerThread.start();
    CustomerThread.start();
  }
}

運(yùn)行結(jié)果如下

Set的值是:1564733938518_27520480474279
Get的值是:1564733938518_27520480474279
Set的值是:1564733938518_27520480498378
Get的值是:1564733938518_27520480498378
Set的值是:1564733938518_27520480540254
Get的值是:1564733938518_27520480540254
······

生產(chǎn)者和消費(fèi)者交替運(yùn)行,生產(chǎn)者生產(chǎn)一個(gè)字符串,緩沖區(qū)為滿,消費(fèi)者消費(fèi)一個(gè)字符串,緩沖區(qū)為空,循環(huán)往復(fù),滿足生產(chǎn)者/消費(fèi)者模型。

await()/signal()生產(chǎn)者/消費(fèi)者模型

緩沖區(qū)

public class ValueObject {
  public static String value = "";
}

ThreadDomain48繼承ReentrantLock,set方法生產(chǎn),get方法消費(fèi)

public class ThreadDomain48 extends ReentrantLock
{
  private Condition condition = newCondition();

  public void set()
  {
    try
    {
      lock();
      while (!"".equals(ValueObject.value))
        condition.await();
      ValueObject.value = "123";
      System.out.println(Thread.currentThread().getName() + "生產(chǎn)了value, value的當(dāng)前值是" + ValueObject.value);
      condition.signal();
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
    finally
    {
      unlock();
    }
  }

  public void get()
  {
    try
    {
      lock();
      while ("".equals(ValueObject.value))
        condition.await();
      ValueObject.value = "";
      System.out.println(Thread.currentThread().getName() + "消費(fèi)了value, value的當(dāng)前值是" + ValueObject.value);
      condition.signal();
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
    finally
    {
      unlock();
    }
  }
}

MyThread41啟動(dòng)兩個(gè)生產(chǎn)線程和一個(gè)消費(fèi)線程

public class MyThread41 {
  public static void main(String[] args)
  {
    final ThreadDomain48 td = new ThreadDomain48();
    Runnable producerRunnable = new Runnable()
    {
      public void run()
      {
        for (int i = 0; i < Integer.MAX_VALUE; i++)
          td.set();
      }
    };
    Runnable customerRunnable = new Runnable()
    {
      public void run()
      {
        for (int i = 0; i < Integer.MAX_VALUE; i++)
          td.get();
      }
    };
    Thread ProducerThread1 = new Thread(producerRunnable);
    ProducerThread1.setName("Producer1");
    Thread ProducerThread2 = new Thread(producerRunnable);
    ProducerThread2.setName("Producer2");
    Thread ConsumerThread = new Thread(customerRunnable);
    ConsumerThread.setName("Consumer");
    ProducerThread1.start();
    ProducerThread2.start();
    ConsumerThread.start();
  }
}

輸出結(jié)果如下

Producer1生產(chǎn)了value, value的當(dāng)前值是123
Consumer消費(fèi)了value, value的當(dāng)前值是
Producer1生產(chǎn)了value, value的當(dāng)前值是123

為什么Producer2無法生產(chǎn),消費(fèi)者無法消費(fèi)呢?是因?yàn)榇藭r(shí)緩沖區(qū)為滿,Producer1的notify()應(yīng)該喚醒Consumer卻喚醒了Producer2,導(dǎo)致Producer2因?yàn)榫彌_區(qū)為滿和Consumer沒有被喚醒而處于waiting狀態(tài),此時(shí)三個(gè)線程均在等待,出現(xiàn)了假死。

解決方案有兩種:

1.讓生產(chǎn)者喚醒所有線程,在set方法中使用condition.signalAll();

2.使用兩個(gè)Condition,生產(chǎn)者Condition和消費(fèi)者Condition,喚醒指定的線程;

正常輸入如下:

······
Producer2生產(chǎn)了value, value的當(dāng)前值是123
Consumer消費(fèi)了value, value的當(dāng)前值是
Producer2生產(chǎn)了value, value的當(dāng)前值是123
Consumer消費(fèi)了value, value的當(dāng)前值是
Producer2生產(chǎn)了value, value的當(dāng)前值是123
Consumer消費(fèi)了value, value的當(dāng)前值是
Producer1生產(chǎn)了value, value的當(dāng)前值是123
Consumer消費(fèi)了value, value的當(dāng)前值是
Producer1生產(chǎn)了value, value的當(dāng)前值是123
Consumer消費(fèi)了value, value的當(dāng)前值是
Producer1生產(chǎn)了value, value的當(dāng)前值是123
Consumer消費(fèi)了value, value的當(dāng)前值是
Producer1生產(chǎn)了value, value的當(dāng)前值是123
Consumer消費(fèi)了value, value的當(dāng)前值是
Producer1生產(chǎn)了value, value的當(dāng)前值是123
Consumer消費(fèi)了value, value的當(dāng)前值是
······

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

南丰县| 溆浦县| 陈巴尔虎旗| 楚雄市| 宜州市| 锦屏县| 井冈山市| 铜梁县| 淳安县| 芮城县| 建宁县| 宁乡县| 耒阳市| 青田县| 湄潭县| 砚山县| 吴桥县| 武山县| 巴中市| 金湖县| 太和县| 普安县| 杭锦后旗| 中牟县| 嵊州市| 理塘县| 吴江市| 桃江县| 遂川县| 德昌县| 顺平县| 灵山县| 九龙县| 通海县| 阿拉尔市| 永春县| 云龙县| 新闻| 浦江县| 天祝| 长子县|