2017年6月30日 下午5:09
1 2 3 4 5 6 7 8 9 10 11 class SteamBread { int id; SteamBread(int id){ this .id = id; } public String toString () { return "steamBread:" +id; } }
1
class SyncStack {
int index = 0 ;
SteamBread[] stb = new SteamBread[6 ];
public synchronized void push (SteamBread sb) {
while (index==stb.length){
try {
this .wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this .notify();
stb[index] = sb;
this .index++;
}
public synchronized SteamBread pop () {
while (index==0 ){
try {
this .wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this .notify();
this .index--;
return stb[index];
}
}
1
class Producer implements Runnable {
SyncStack ss = null ;
Producer(SyncStack ss){
this .ss = ss;
}
@Override
public void run () {
for (int i=0 ;i<20 ;i++){
SteamBread stb = new SteamBread(i);
ss.push(stb);
System.out.println("生产了" +stb);
try {
Thread.sleep(10 );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
1
class Consume implements Runnable {
SyncStack ss = null ;
public Consume (SyncStack ss) {
super ();
this .ss = ss;
}
@Override
public void run () {
for (int i=0 ;i<20 ;i++){
SteamBread stb = ss.pop();
System.out.println("消费了" +stb);
try {
Thread.sleep(100 );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
1 2 package thread;
public class ProduceConsume {
public static void main (String[] args) {
SyncStack ss = new SyncStack();
Producer p = new Producer(ss);
Consume c = new Consume(ss);
Thread tp = new Thread(p);
Thread tc = new Thread(c);
tp.start(); tc.start();
}
}
如何思考: 1. 根据我对算法的总结“先生活例子,然后提取概括,后算法实现”的思路
2. 我们先想这几个问题:
1. 堆栈空了怎么办:消费者停止消费
2. 堆栈满了怎么办:生产者停止生产
3. 那么:我们既然要实现停止的功能,这时就得想到**线程**
4. 因为:如果不用runnable,那么方法执行其不可控,只能一次执行完,或者出错一般的改写
3. 如果生产和消费同时进行怎么办:**sync**
4. 如何保证只用一个栈呢:**引用传参**
5. 容易忽略的问题:
1. 既然生产和消费者都能停止,那么何时唤醒呢?
2. 这个问题关键不是如何解决,而是注意到这个问题。
3. **结论:等待 唤醒成对出现**
4. **生产的时候唤醒消费,消费的时候唤醒生产**
5. **生产暂停生产 ,消费暂停生产**
6. 实现:
1. 先馒头 -> 栈 -> 生产者 -> 消费者 -> 总类总结讨论: 1. 在这个实下中**一个消费者 ,一个生产者 ,一个栈**
2. 如果同一个消费者执行多次start(),同一个消费者也执行多次start()呢(图1)? 图1 这时还是共享一个资源 3. 如果多个消费者,多个生产者呢(图2)并且在生产者消费中将栈都声明为static ? 图2 这时还是共享一个资源 4. 如果多个消费者,多个生产者呢,但是却不将生产者消费中将栈声明为static ? 1. 这时,两个消费者使用不同的资源,两个消费也使用不同的资源 2. 但是,由于是引用类型,本质内存中只有一个资源空间 3. 程序就乱了!!!!!
注:在多线程中,虽然我们使用了多线程,但是其实一个具体的时刻还是只有一个线程运行,变得只是这些各自的多线程会走走停停,交互运行