线程之间的协作通常是 使用 生产者消费者模式去解决的
生产者消费者模式 不是设计模式, (设计模式是指面向对象处理类和类之间的关系,更好的组织代码的套路);是处理线程之间关系的模式;
现在一般公司的架构模式也都是数据库---》服务器--》 前端, 在服务端和前端之前写个中间件来协调之间的响应关系就是生产者和消费者模式;好处是通过中间缓冲层来解耦;一般是使用消息队列来做的
麦当劳 先收钱 收完钱等着生产; 这就是生产者消费者模式;一对多
肯德基 先点单 ,生产好了以后收钱;这是BIO模式;一对一;会有一个队列;
两个模式都是性能比较好的, 分别有不同的使用场景;
这里需要synchronized, 老祖宗object的wait和notify方法(等待和通知);
生产者消费者模式 具体到线程协作上 两种方法去解决,根据应用场景不同来使用
1,管程法 ;利用管道(容器缓冲区)来做;
2,红绿灯法 ;利用flag来做;
下面分别介绍
1,管程法
生产者从缓存区存数据,消费者从缓存区取数据,缓冲区是一个并发容器;
package y.i.d;
public class CoTest01 {
public static void main(String[] args){
SyncContainer container = new SyncContainer();
new Provider(container).start();
new Productor(container).start();
}
}
// 生产者
class Provider extends Thread{
SyncContainer container;
public Provider(SyncContainer container) {
this.container= container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("生产-->"+i+"个馒头");
container.push(new Steamedbun(i));
}
}
}
//消费者
class Productor extends Thread{
SyncContainer container;
public Productor(SyncContainer container) {
this.container= container;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("消费-->"+container.pop().id+"个馒头");
}
}
}
// 缓冲区
class SyncContainer{
Steamedbun[] buns= new Steamedbun[10];
int count =0;
// 存储
public synchronized void push(Steamedbun bun) {
if(count==buns.length) { // 如果等于数组长度说明容器没有空间需要等待了
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
buns[count]=bun;
count++;
this.notifyAll();
}
//消费
public synchronized Steamedbun pop() {
if(count==0) { // 如果等于0说明容器没有数据 可以消费了 等待就可以了
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
count--;
this.notifyAll();
return buns[count];
}
}
//馒头
class Steamedbun{
int id;
public Steamedbun(int id) {
this.id=id;
}
}
2,红绿灯法
package y.i.d;
public class CoTest02 {
public static void main(String[] args){
Tv tv = new Tv();
new Player(tv).start();
new Watcher(tv).start();
}
}
class Player extends Thread{
Tv tv;
public Player(Tv tv) {
this.tv=tv;
}
public void run() {
for (int i = 0; i < 20; i++) {
if(i%2==0) {
this.tv.play("123");
}else {
this.tv.play("456");
}
}
}
}
class Watcher extends Thread{
Tv tv;
public Watcher(Tv tv) {
this.tv=tv;
}
public void run() {
for (int i = 0; i < 20; i++) {
this.tv.watch();
}
}
}
class Tv extends Thread{
boolean flag = true;
String voice;
public synchronized void play(String str) {
if(!flag) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.voice = str;
System.out.println("show"+str);
this.notifyAll();
this.flag =!this.flag;
}
public synchronized void watch() {
if(flag) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("watch"+this.voice);
this.flag =!this.flag;
this.notifyAll();
}
}