真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java多線程中生產(chǎn)者消費(fèi)者模型的示例分析

小編給大家分享一下Java多線程中生產(chǎn)者消費(fèi)者模型的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)憑借在網(wǎng)站建設(shè)、網(wǎng)站推廣領(lǐng)域領(lǐng)先的技術(shù)能力和多年的行業(yè)經(jīng)驗(yàn),為客戶提供超值的營(yíng)銷型網(wǎng)站建設(shè)服務(wù),我們始終認(rèn)為:好的營(yíng)銷型網(wǎng)站就是好的業(yè)務(wù)員。我們已成功為企業(yè)單位、個(gè)人等客戶提供了網(wǎng)站建設(shè)、網(wǎng)站制作服務(wù),以良好的商業(yè)信譽(yù),完善的服務(wù)及深厚的技術(shù)力量處于同行領(lǐng)先地位。

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

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

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

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

當(dāng)

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

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

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

制作一個(gè)簡(jiǎn)單的緩沖區(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無(wú)法生產(chǎn),消費(fèi)者無(wú)法消費(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)前值是
······

以上是“Java多線程中生產(chǎn)者消費(fèi)者模型的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


分享名稱:Java多線程中生產(chǎn)者消費(fèi)者模型的示例分析
鏈接分享:http://weahome.cn/article/poggpp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部