java多线程在日常开发中基本上是很常用的,我们假设现在有这样的一个情况,生产者生产一个物品的同时要让消费者取走。生产者要将自己生产的一个产品交到一个公共的区域(商城,超市),让消费者去取走(购买)。所以这个时候我们要考虑到线程同步和线程重复取值的一个问题。(同步--> synchronized,重复取值--->设定一个标记值,当达到条件时执行,未满足条件时等待)
下面是我们详细的代码实现:
class Messager{ //定义一个 生产者和消费者的中间类 保持数据和取走数据 private String name; private String note; private boolean flag = false; //flag --> flase 假设当fasle的时候,只可以生产,不可以取走 //flag --> true 假设当true的时候 ,消费者能取走,生产者不能生产 public synchronized void set(String name,String note){ //生产者生产数据 if(this.flag == true){ try { super.wait(); //生产者不能生产数据,线程等待 } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name; //假设生产花费了一定的时间,产生了时间误差 try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } this.note = note; this.flag = true; //生产完毕,消费者可以取走数据 super.notify(); //唤醒其他等待线程 } public synchronized void get(){ if(this.flag == false){ try { // flase-->false 只可以生产,不可以取走,让当前线程等待 uper.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //假设取走花费了一定的时间 try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("生产的名称:"+this.name+"生产的内容:"+this.note); this.flag = false; //数据已经取走,改变当前标记 super.notify(); //唤醒其他等待线程 } } class Producter implements Runnable{ //生产者生产数据 private Messager msg; public Producter(Messager msg){ this.msg = msg; } @Override public void run() { //线程主体 假设A、B各生产五次 for(int i=0; i<10;i++){ if(i%2==0){ msg.set("物品A", "物品A制作完毕。"); }else{ msg.set("物品B","物品B制作完毕。"); } } } } class Consumer implements Runnable{ private Messager msg; public Consumer(Messager msg){ this.msg = msg; } @Override public void run() { //线程主体 将生产的十个产品取出 for (int x=0 ;x<10; x++){ msg.get(); } } } public class Test{ public static void main(String args[]){ Messager msg = new Messager(); //定义一个公共存放取出区域 new Thread(new Producter(msg)).start(); //启动生产线程 new Thread(new Consumer(msg)).start(); //启动消费线程 } }