线程同步实例(生产者和消费者的问题),这个例子也是面试中可能被问到的一道问题,现将学习笔记总结如下:
解决问题思路及具体代码实现如下:
1. 面向对象分析:
- 提取对象;(分析名词)
- 对象有哪些方法;
- 根据类(对象)的类型确定是否是线程;
2.对象(类):
2.1馒头(个数) int id;
2.2筐子(馒头数组);
2.2.1筐子的方法(为了互不影响,各自加锁):
- 放馒头;
- 取馒头;
2.3生产者(线程):
- 筐子;
- 放馒头。
2.4 消费者(线程):
- 筐子;
- 取馒头。
3.具体代码以及结果如下:
package javaBasic.threads;
/**
* @author yn
* @description 生产者和消费者的问题
*/
public class ProducerConsumer {
public static void main(String [] args){
SyncStack ss= new SyncStack();
Producer p = new Producer(ss);
Consumer c = new Consumer(ss);
new Thread(p).start();
new Thread(c).start();
}
}
class WoTou{
int id;
WoTou(int id){
this.id = id;
}
public String toString(){
return "WoTou :" + id;
}
}
class SyncStack{
int index = 0;
WoTou[] array = new WoTou[6];
public synchronized void push(WoTou wt) throws Exception{
if (index ==array.length){
this.wait();
}
this.notify();
array[index] = wt;
index++;
}
public synchronized WoTou pop() throws Exception{
if (index == 0){
this.wait();
}
this.notify();
index--;
return array[index];
}
}
class Producer implements Runnable{
SyncStack ss = null;
Producer(SyncStack ss){
this.ss = ss;
}
public void run(){
for (int i =0;i<20;i++){
WoTou woTou = new WoTou(i);
try {
ss.push(woTou);
System.out.println("生产了:" + woTou);
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
SyncStack ss = null;
Consumer(SyncStack ss){
this.ss = ss;
}
public void run(){
for (int i =0;i<20;i++){
WoTou woTou = null;
try {
woTou = ss.pop();
System.out.println("消费了:" + woTou);
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(woTou);
}
}
}
输出:
消费了:WoTou :0
生产了:WoTou :0
生产了:WoTou :1
生产了:WoTou :2
生产了:WoTou :3
生产了:WoTou :4
WoTou :0
消费了:WoTou :4
生产了:WoTou :5
生产了:WoTou :6
生产了:WoTou :7
WoTou :4
消费了:WoTou :7
生产了:WoTou :8
WoTou :7
消费了:WoTou :8
生产了:WoTou :9
WoTou :8
消费了:WoTou :9
生产了:WoTou :10
WoTou :9
消费了:WoTou :10
生产了:WoTou :11
WoTou :10
消费了:WoTou :11
生产了:WoTou :12
WoTou :11
消费了:WoTou :12
生产了:WoTou :13
WoTou :12
消费了:WoTou :13
生产了:WoTou :14
WoTou :13
消费了:WoTou :14
生产了:WoTou :15
WoTou :14
消费了:WoTou :15
生产了:WoTou :16
WoTou :15
消费了:WoTou :16
生产了:WoTou :17
WoTou :16
生产了:WoTou :18
消费了:WoTou :17
WoTou :17
消费了:WoTou :18
生产了:WoTou :19
WoTou :18
消费了:WoTou :19
WoTou :19
消费了:WoTou :6
WoTou :6
消费了:WoTou :5
WoTou :5
消费了:WoTou :3
WoTou :3
消费了:WoTou :2
WoTou :2
消费了:WoTou :1
WoTou :1
生产和消费的时间间隔不一样:生产的生产自己的,生产够了就停了,消费的继续消费,直到消费完。
4.修改:if改成while;
- if中包含try…catch的时候,catch完了会继续执行,但实际已经超过使用条件了。
- 如果使用while,try…catch完了之后依旧是这个条件的判断,不会继续往下执行。
- 教科书中会使用while。
学习最好的方式就是理解相关领域的各个知识,在使用的时候能根据需求选择对应的知识点,这才是以学为用。
不足之处欢迎大家留言批评指正。