Java-线程(生产者消费者模式)
来源:互联网 发布:刺客信条黑旗优化差 编辑:程序博客网 时间:2024/05/22 14:14
普通的生产者消费者模式:
package ss;/** * 线程通讯实例: * * 生产者消费者模式 * *///产品类class Product{ String name;//名字 double price;//价格 boolean flag=false;//产品是否生产完毕的标签,默认情况是没有生产完成。}//生产者class Producer extends Thread{ //产品 Product p; public Producer(Product p){ this.p=p; }@Overridepublic void run() { int i=0; while(true){ synchronized (p) { if(p.flag==false){ if(i%2==0){ p.name="苹果"; p.price=6.5; }else{ p.name="香蕉"; p.price=2.0; } System.out.println("生产者生产出了: "+p.name+"价格是: "+p.price); p.flag=true; i++; p.notifyAll();//唤醒消费者去消费 }else{ //已经生产完毕,等待消费者先去消费 try { p.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }}}//消费者class Customer extends Thread{ Product p; public Customer(Product p){ this.p=p; } @Override public void run() { while(true){ synchronized (p) { if(p.flag==true){//产品已经生产完毕 System.out.println("消费者消费了"+p.name+"价格: "+p.price); p.flag=false; p.notifyAll();//唤醒生产者去生产 }else{ //产品还有生产,等待生产者先生产 try { p.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }}public class Demo { public static void main(String[] args) { Product p=new Product();//产品 //创建生产者 Producer producer=new Producer(p); //创建消费 Customer customer=new Customer(p); //调用start方法开启线程 producer.start(); customer.start(); }}
队列实现生产者消费者模式:
- 在Java多线程应用中,队列的使用率很高,多数生产者消费者模型的首选数据结构就是队列(先进先出)。
- Java提供线程安全的Queue可以分为阻塞式队列和非阻塞式队列。
- 阻塞式队列的典型例子就是BlockingQueue.当前线程没有数据或者数据满了的时候会阻塞。
- 非阻塞式队列的典型例子就是LinkedList(双向列表)
/*** * Collection(list,set,queue) * @author pjy * * LinkedList是一个Deque(双重队列)入口可以添加数据,入口也可以移除数据 */public class ThreadCommunictaion01 { public static void main(String[] args) throws Exception{ List<String> list= new ArrayList<String>(2); list.add("a1"); list.add("a2"); list.add("a3"); list.add("a4"); System.out.println("list.size()="+list.size()); //阻塞式队列 final BlockingQueue<String> q1= new ArrayBlockingQueue<>(3); new Thread(){ public void run(){ try{ String s=q1.take();//阻塞式方法,没有数据则等待 //String s=q1.remove();//没有数据会抛出异常 System.out.println("s="+s); }catch(Exception e){ e.printStackTrace(); } }; }.start(); q1.put("A"); q1.put("B"); q1.put("C"); //当队列满以后,当前线程会阻塞 q1.put("D");//此方法满了会阻塞 //q1.add("A");此方法满了会抛出异常 System.out.println("q1.size()="+q1.size()); }}
案例:简单的生产者消费者模式:一边放,一边取
- BlockingQueue队列:
import java.util.Scanner;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;/** * * 生产者:向容器放数据,此容器从键盘读入字符串 * 存储到容器(阻塞式队列)中 * */class Producer extends Thread{//is a //has a (关联) private BlockingQueue<String> queue; public Producer(BlockingQueue<String> queue) { this.queue=queue; } @Override public void run() { Scanner sc=new Scanner(System.in); while(true){ //从键盘读入一个字符串 System.out.println("放数据:"); String s=sc.nextLine(); try{ //将字符串放入容器 queue.put(s); }catch(Exception e){e.printStackTrace();} } }} /**消费者:从容器中取数据*/class Consumer extends Thread{ //has a (关联) private BlockingQueue<String> queue; public Consumer(BlockingQueue<String> queue) { this.queue=queue; } @Override public void run() { while(true){ try{ System.out.println("take:"+queue.take()); }catch(Exception e){e.printStackTrace();} } }}public class ThreadCommunication02 { public static void main(String[] args) { //容器 BlockingQueue<String> container=new LinkedBlockingQueue<String>(3); //构建线程对象 Producer p=new Producer(container); Consumer c=new Consumer(container); //启动线程 p.start(); c.start(); //一边放一边取(简单地生产者消费者模式) }}
- LinkedList队列:
import java.util.LinkedList;import java.util.Scanner;import java.util.concurrent.BlockingQueue;/**生产者向容器放数据,此容器从键盘读入字符串 * 存储到容器(非阻塞式队列)中*/class Producer02 extends Thread{//is a //has a (关联) private LinkedList<String> queue; public Producer02(LinkedList<String> queue) { this.queue=queue; } @Override public void run() { Scanner sc=new Scanner(System.in); while(true){ //从键盘读入一个字符串 System.out.println("放数据:"); String s=sc.nextLine();//阻塞方法 synchronized (this) { try{ //将字符串放入容器 queue.addLast(s); //通知消费者取 queue.notify(); }catch(Exception e){e.printStackTrace();} } } }}/**消费者从容器中取数据*/class Consumer02 extends Thread{ //has a (关联) private LinkedList<String> queue; public Consumer02(LinkedList<String> queue) { this.queue=queue; } @Override public void run() { while(true){ synchronized (this) { //容器内容为空时则等待 if(queue.size()==0)try{queue.wait();}catch(Exception e){} //取数据 try{ System.out.println("take:"+queue.removeFirst()); }catch(Exception e){e.printStackTrace();} //通知消费者继续方法 //queue.notify(); } } }}public class ThreadCommunication03 { public static void main(String[] args) { //容器 LinkedList<String> container= new LinkedList<String>(); //构建线程对象 Producer02 p=new Producer02(container); Consumer02 c=new Consumer02(container); //启动线程 p.start(); c.start(); }}
- ArrayList:
class Producer03 extends Thread{ @Override public void run() { Scanner sc=new Scanner(System.in); while(true){ String data=sc.nextLine(); //放数据 } }}class Consumer03 extends Thread{ @Override public void run() { while(true){ //取数据 } }}class Container03{ private List<String> list; /**@param 容量*/ public Container03(int cap) { list=new ArrayList<>(cap); } /**放数据*/ public synchronized void put(String data){ //1.判断容器是否已满,满则等待 //2.放数据 //3.通知消费者取数据 } /**取数据*/ public synchronized void take(){ //1.判断容器是否为空,空则等待 //2.取数据 //3.通知生产者放数据 }}public class ThreadCommunication04 {}
wait()与notify()
wait():
等待,如果线程执行了wait方法,那么该线程会进入等待的状态,等待状态下的线程必须要被其他线程调用notify方法才能唤醒。
一个线程如果执行了wait方法,那么该线程就会进去一个以锁对象为标识符的线程池中等待。
notify():
唤醒 唤醒等待的方法。
如果一个线程执行了notify方法,那么会唤醒以锁对象为标识符中等待线程中其中一个。
wait与notify方法要注意的事项:
1、wait方法与notify方法是属于Object对象的。
2、wait方法与notify方法必须要在同步代码块或者是同步函数中才能使用。
3、wait方法与notify方法必须要由锁对象调用。
0 0
- Java-线程(生产者消费者模式)
- Java线程(2)线程协作-生产者/消费者模式
- java线程(生产者/消费者)
- Java中的线程(七)- 生产者消费者模式
- java线程通信 生产者与消费者模式
- java线程之生产者与消费者模式
- 线程池 生产者 消费者 模式 JAVA进阶
- 线程--生产者消费者模式
- 生产者消费者模式(java)
- java 线程生产者消费者
- 生产者消费者模式(同步线程)
- 消费者-生产者模式(线程的实现)
- Java生产者消费者模式
- 生产者消费者模式---java
- 生产者/消费者模式 (java)
- java 消费者、生产者模式
- java 生产者消费者模式
- 生产者消费者模式 JAVA
- 136. Single Number
- matlab 蠓虫分类问题 &n…
- matlab newlvq函数 建立…
- matlab dist函数 …
- 知道这20个正则表达式,能让你少写1,000行代码
- Java-线程(生产者消费者模式)
- matlab linkage函数 计…
- ios动画笔记(2)CATransform3D和CASpringAnimation 、CATransition和CAEmitterLayer、UIDynamicAnimator
- matlab corrcoef 函数&n…
- springMVC和tiles的整合
- matlab factoran 因子分析函数
- 剑指Offer面试题24二叉搜索树的后序遍历序列(递归),面试题25二叉树中和为某一值的路径(栈)
- [思路题] Codeforces 354C #206 (Div. 1) C. Vasya and Beautiful Arrays
- matlab regress函数 最…