生产者消费者原理解释:
生产者消费者的模型是指的是在多个线程间同时操作同一快的内存;一部分的线程向内存中添加数据(生产者) 一部分线程将内存中的数据取出并再这一块的内存中取消该数据(消费者);当内存中没有数据的时候 消费者等待生产者填入数据后才继续执行;当内存中的数据填满的时候生产者等待消费者取出数据后才继续生产。
用java自带的线程安全的LinkedBlockingDeque实现生产者消费者,相当的简单如下:
包结构:
代码实现由4部分:
1:线程间保存数据的仓库 stack;
2:生产者线程 --->用于向仓库中保存数据;
3:消费者线程--->用于取出仓库中的数据;
4:调用的main方法;
各个步骤的代码如下:
1:线程间保存数据的仓库 stack;
package stackStu; import java.util.concurrent.LinkedBlockingDeque; /** * java模拟的栈类 * Created by admin on 2017/2/15. */ public class Stack { /** * 用于保存数据的仓库 */ private LinkedBlockingDeque<String> stringList; public Stack() { this.stringList = new LinkedBlockingDeque<>(5); } /** * 向栈中添加数据 * @param str 栈中需要添加的数据 */ public void Push(String str) throws InterruptedException { stringList.put(str); } /** * 获取栈中的数据,如果没有数据就返回null. * @return 返回的栈的最顶端的数据。 */ public String Pop() throws InterruptedException { return this.stringList.take(); } @Override public String toString() { return "Stack{" + "stringList=" + stringList + '}'; } }
2:生产者线程 --->用于向仓库中保存数据;
package stackStu; /** * 用于弹入数据的子线程 * Created by admin on 2017/2/15. */ public class MThreadPush extends MThreadPop { private int i; public MThreadPush(Stack stack) { super(stack); i = 0; } @Override protected void operation() throws InterruptedException { System.out.println("--------------------->push" + i); this.getStack().Push(String.valueOf(i++)); } }
3:消费者线程--->用于取出仓库中的数据;
package stackStu; /** * 子线程 * 用于弹出数据并打印。 * Created by admin on 2017/2/15. */ public class MThreadPop extends Thread { /** * 需要执行的数据的引用 */ private Stack stack; /** * 表示运行的字段 */ private boolean isRun; public MThreadPop(Stack stack) { super(); this.stack = stack; } @Override public void run() { super.run(); while (this.isRun){ try { Thread.sleep(1000); this.operation(); } catch (InterruptedException e) { // e.printStackTrace(); } } } protected void operation() throws InterruptedException { String str = null; try { str = this.stack.Pop(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("--------------------->pop" + str); } @Override public synchronized void start() { super.start(); } public boolean isRun() { return isRun; } public void setRun(boolean run) { isRun = run; } public Stack getStack() { return stack; } }
4:调用的main方法;
package stackStu; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * java 模拟栈的主函数 * Created by admin on 2017/2/15. */ public class StackMain { public static void main(String... args) { Stack stack = new Stack(); MThreadPop pop = new MThreadPop(stack); MThreadPush push = new MThreadPush(stack); pop.setRun(true); push.setRun(true); // sysPrint(stack); //向栈中循环添加数据 push.start(); // sysPrint(stack); //打印所有的栈的数据 pop.start(); // sysPrint(stack); // ExecutorService service = Executors.newCachedThreadPool(); // service.submit(push); // service.submit(pop); try { Thread.sleep(10000); // service.shutdownNow(); pop.setRun(false); push.setRun(false); // service.shutdown(); Thread.sleep(1000*2); } catch (InterruptedException e) { System.out.println("-------InterruptedException------------>end"); e.printStackTrace(); } System.out.println("------------------->end"); } private static void sysPrint(Stack stack) { System.out.println(stack.toString()); } private static void sysPrint(String str) { System.out.println(str); } }