首先,我利用忙测试写出了第一次版本的代码
1 package How; 2 //自写代码 缺陷 无法完全实现pv操作线程处于忙测试状态 3 public class bin_1_1 4 { 5 6 public static void main(String[] args) 7 { 8 Producter producter; //生产者线程 9 Consumer consumer; //消费者线程 10 Buffer buffer; 11 buffer=new Buffer(10); 12 producter =new Producter(buffer); 13 consumer =new Consumer(buffer); 14 producter.start(); 15 consumer.start(); 16 } 17 18 } 19 class Producter extends Thread 20 { 21 Buffer buffer; 22 public Producter(Buffer buffer) 23 { 24 this.buffer=buffer; 25 } 26 public void run() 27 { 28 while(true) 29 { 30 31 try 32 { 33 //模拟数据生产时间 34 Thread.sleep((int)Math.random()*5000+400); 35 IsEmpty(); //p(Empty) 36 //寻找空的缓存区 记录其标号为K 37 int k = 0; 38 for(int i=0; i<buffer.state_of_objs.length; i++) 39 { 40 if(buffer.state_of_objs[i]==0) 41 { 42 k=i; 43 break; 44 } 45 46 } 47 write(k); 48 } 49 catch (InterruptedException e) 50 { 51 52 e.printStackTrace(); 53 } 54 55 } 56 } 57 synchronized public void IsEmpty() throws InterruptedException 58 { 59 60 while(true) 61 { 62 if(buffer.empty==0) 63 { 64 this.sleep(1); 65 } 66 else 67 { 68 buffer.empty--; 69 break; 70 } 71 } 72 } 73 public void write( int k ) //写入互斥,进制其他生产者访问 74 { 75 try 76 { 77 //模拟数据写入时间 78 Thread.sleep((int)Math.random()*1000+100); 79 //更改状态 80 System.out.println(Thread.currentThread().getName()+": 写"+k+"号缓存区"); 81 buffer.state_of_objs[k]=1; 82 buffer.full++; 83 } catch (InterruptedException e) 84 { 85 e.printStackTrace(); 86 } 87 } 88 } 89 class Consumer extends Thread 90 { 91 Buffer buffer; 92 public Consumer(Buffer buffer) 93 { 94 this.buffer=buffer; 95 } 96 public void run() 97 { 98 while(true) 99 { 100 try 101 { 102 IsFull(); 103 int k = 0; 104 for(int i=0; i<buffer.state_of_objs.length; i++) 105 { 106 if(buffer.state_of_objs[i]==1) 107 { 108 k=i; 109 break; 110 } 111 } 112 read(k); 113 //模拟消费时间 114 Thread.sleep((int)Math.random()*5000+300); 115 } 116 catch (InterruptedException e) 117 { 118 e.printStackTrace(); 119 } 120 } 121 } 122 synchronized public void IsFull() throws InterruptedException 123 { 124 125 while(true) 126 { 127 if(buffer.full==0) 128 { 129 this.sleep(1); 130 } 131 else 132 { 133 buffer.full--; 134 break; 135 } 136 } 137 } 138 public void read( int k) 139 { 140 try 141 { 142 //模拟读时间 143 Thread.sleep((int)Math.random()*3000+250); 144 System.out.println(Thread.currentThread().getName()+": 读"+k+"号缓存区"); 145 //更改状态 146 buffer.state_of_objs[k]=0; 147 buffer.empty++; 148 } catch (InterruptedException e) 149 { 150 e.printStackTrace(); 151 } 152 } 153 } 154 class Buffer //缓存区 临界资源记录区 155 { 156 int size; //缓存区大小 157 Object[] objs; // 158 int full=0; 159 int empty; 160 int []state_of_objs; 161 public Buffer(int size) 162 { 163 this.size=size; 164 this.empty=size; 165 objs =new Object[size]; 166 state_of_objs=new int[size]; 167 for(int i=0; i<size; i++) 168 { 169 state_of_objs[i]=0; 170 } 171 } 172 }
针对上述情况我,参考了一些其他人的代码
package How; //参考代码 主要学习线程的各种锁! public class bin_1_2 { private static Integer count = 0; private final Integer FULL = 10; private static String LOCK = "LOCK"; class Producer implements Runnable { @Override public void run() { for (int i = 0; i < 10; i++) { try { Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); } synchronized (LOCK) { while (count == FULL) { try { LOCK.wait(); } catch (Exception e) { e.printStackTrace(); } } count++; System.out.println(Thread.currentThread().getName() + "生产者生产,目前总共有" + count); LOCK.notifyAll(); } } } } class Consumer implements Runnable { @Override public void run() { for (int i = 0; i < 10; i++) { try { Thread.sleep(3000); } catch (InterruptedException e1) { e1.printStackTrace(); } synchronized (LOCK) { while (count == 0) { try { LOCK.wait(); } catch (Exception e) { } } count--; System.out.println(Thread.currentThread().getName() + "消费者消费,目前总共有" + count); LOCK.notifyAll(); } } } } public static void main(String[] args) throws Exception { bin_1_2 bin_1_2 = new bin_1_2(); new Thread(bin_1_2.new Producer()).start(); new Thread(bin_1_2.new Consumer()).start(); new Thread(bin_1_2.new Producer()).start(); new Thread(bin_1_2.new Consumer()).start(); new Thread(bin_1_2.new Producer()).start(); new Thread(bin_1_2.new Consumer()).start(); new Thread(bin_1_2.new Producer()).start(); new Thread(bin_1_2.new Consumer()).start(); } }
这个代码为 多个消费者,生产者的问题,通过这个代码,我了解了synchronized使用方式。
package How; //参考代码 import java.util.LinkedList; public class bin_1_3 { private LinkedList<Object> storeHouse = new LinkedList<Object>(); private int MAX = 10; public bin_1_3() { } public void start() { new Producer().start(); new Comsumer().start(); } class Producer extends Thread { public void run() { while (true) { synchronized (storeHouse) { try { while (storeHouse.size() == MAX) { System.out.println("storeHouse is full , please wait"); storeHouse.wait(); } Object newOb = new Object(); if (storeHouse.add(newOb)) { System.out.println("Producer put a Object to storeHouse"); Thread.sleep((long) (Math.random() * 3000)); storeHouse.notify(); } } catch (InterruptedException ie) { System.out.println("producer is interrupted!"); } } } } } class Comsumer extends Thread { public void run() { while (true) { synchronized (storeHouse) { try { while (storeHouse.size() == 0) { System.out.println("storeHouse is empty , please wait"); storeHouse.wait(); } storeHouse.removeLast(); System.out.println("Comsumer get a Object from storeHouse"); Thread.sleep((long) (Math.random() * 3000)); storeHouse.notify(); } catch (InterruptedException ie) { System.out.println("Consumer is interrupted"); } } } } } public static void main(String[] args) throws Exception { bin_1_3 pc = new bin_1_3(); pc.start(); } }
这个代码学习到了 LinkedList这个类库,从此我便可以快捷的方式实现栈,队列
最后我的改进代码如下:
package How; class MyBuffer // 模拟缓冲区,这个为临界资源 { String data; //模拟缓存区存放的数据 public MyBuffer(String data) { this.data=data; } } public class bin_1 { public static void main(String[] args) { MyBuffer buffer=new MyBuffer(""); MyConsumer myConsumer=new MyConsumer(buffer); MyProducter myProducter=new MyProducter(buffer); myConsumer.start(); myProducter.start(); } } class MyProducter extends Thread { MyBuffer buffer; public MyProducter(MyBuffer buffer) { this.buffer=buffer; } //生产作业 public void ProducterJob() { //模拟生产时间 try { Thread.sleep((int )Math.random()*1000+400); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //进入互斥资源 synchronized (buffer) { if(buffer.data!="") //缓存区满着,阻塞 { try { buffer.wait(); System.out.println("生产者等待"); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } buffer.data=""+System.currentTimeMillis(); System.out.println("生产者 :生产的数据为"+buffer.data); buffer.notify(); //唤醒消费者 } } public void run() { while(true) { ProducterJob(); } } } class MyConsumer extends Thread { MyBuffer buffer; public MyConsumer(MyBuffer buffer) { this.buffer=buffer; } //消费作业 public void ConsumerJob() { //模拟消费时间 try { Thread.sleep((int )Math.random()*1000+600); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //进入互斥资源 synchronized (buffer) { if(buffer.data=="") //缓存区为空,阻塞 { try { buffer.wait(); System.out.println("消费者等待"); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("消费者 :消费的数据为"+buffer.data); buffer.data=""; buffer.notify(); //唤醒生产者 } } public void run() { while(true) { ConsumerJob(); } } }
运行结果: