码迷,mamicode.com
首页 > 编程语言 > 详细

多线程_并发协作

时间:2019-01-24 22:00:20      阅读:294      评论:0      收藏:0      [点我收藏+]

标签:art   voice   高效   containe   return   tac   not   计数器   watcher   

线程通信

解决方法一:并发协作模型“生产者/消费者模式”->管程法

生产者:负责生产数据的模块(这里的模块可能是:方法、对象、线程、进程);

消费者:负责处理数据的模块(这里的模块可能是:方法、对象、线程、进程);

缓冲区:消费者不能直接使用生产者的数据,它们之间有个“缓冲区”;

生产者将生产好的数据放入“缓冲区”,消费者从“缓冲区”拿要处理的数据。

优点:解耦、提高效率。

 

public class Cotest01 {
 public static void main(String[] args) {
  SynContainer container = new SynContainer();
  new Productor(container).start();
  new Consumer(container).start();
 }
}
// 生产者
class  Productor extends Thread{
 SynContainer container;
 public Productor(SynContainer container) {
  this.container = container;
 }

 @Override
 public void run() {
  // 生产
  for (int i = 1; i <= 100; i++) {
   System.out.println("生产-->"+i+"馒头");
   container.push(new Steamedbun(i));
  }
 }
}
// 消费者
class Consumer extends Thread{
 SynContainer container;
 public Consumer(SynContainer container) {
  this.container = container;
 }

 @Override
 public void run() {
  // 消费
  for (int i = 1; i <= 100; i++) {
   System.out.println("消费-->"+container.pop().id+"馒头");
  }
 }
}
// 缓冲区
class SynContainer{
 Steamedbun[] buns = new Steamedbun[10];// 存储容器
 int count = 0;// 计数器
 // 存储 生产
 public synchronized void push(Steamedbun bun) {
  
  
  // 何时能生产 容器存在空间
  // 不能生产 只能等待 消费者通知生产才解除
  if (count ==  buns.length) {
   try {
    this.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  // 存在空间 可以生产
  try {
   Thread.sleep(10);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  buns[count] = bun;
  count++;
  this.notifyAll();// 存在数据 可以通知消费
 }
 // 获取 消费
 public synchronized Steamedbun pop() {
  // 何时消费 容器中是否存在数据
  // 没有数据 只有等待
  if (count == 0) {
   try {
    this.wait();// 线程阻塞 生产者通知消费解除阻塞
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  try {
   Thread.sleep(10);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  // 存在数据可以消费
  count--;
  Steamedbun bun = buns[count];
  this.notifyAll();// 存在空间了,可以唤醒对方生产了
  return bun;
 }
}
// 馒头
class Steamedbun{
 int id;

 public Steamedbun(int id) {
  super();
  this.id = id;
 }
 
}

解决办法二:并发协作模式“生产者/消费者模式”->信号灯法

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) {
  super();
  this.tv = tv;
 }
 
 @Override
 public void run() {
  for (int i = 0; i < 20; i++) {
   if (i%2==0) {
    this.tv.play("奇葩说");
   }else {
    this.tv.play("太污了,喝瓶立白洗洗嘴");
   }
  }
 }
}
// 消费者 观众
class Watcher extends Thread{
 Tv tv;

 public Watcher(Tv tv) {
  super();
  this.tv = tv;
 }
 @Override
 public void run() {
  for (int i = 0; i < 20; i++) {
    tv.watch();
  }
 }
}
// 同一份资源 电视
class Tv{
 String voice;
 // 信号灯
 // T表示演员表演 观众等待
 // F表示观众观看 演员等待
 boolean flag = true;
 
 // 表演
 public synchronized void play(String voice) {
  // 演员等待
  if (!flag) {
   try {
    this.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  
  // 表演时刻
  this.voice = voice;
  System.out.println("表演了:"+voice);
  // 唤醒
  this.notifyAll();
  // 切换标志
  this.flag = !this.flag;
 }
 
 // 观看
 public synchronized void watch() {
  // 观众等待
  if (flag) {
   try {
    this.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  // 观看
  System.out.println("听到了:"+voice);
  
  // 唤醒
  this.notifyAll();
  // 切换标志
  this.flag = !this.flag;
 }
}

多线程_并发协作

标签:art   voice   高效   containe   return   tac   not   计数器   watcher   

原文地址:https://www.cnblogs.com/qust-lgh/p/10316843.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!