生产者消费者问题
①管程法
源代码:
package cn.ecut.pc;
//解决方式一:管程法
public class TestPC {
public static void main(String[] args) {
SynContainer container=new SynContainer();
new Producer(container).start();
new Consumer(container).start();
}
}
//生产者
class Producer extends Thread{
SynContainer container;
public Producer(SynContainer container){
this.container=container;
}
@Override
public void run() {
for (int i = 1; i < 100; i++) {
container.push(new Coke(i));
System.out.println("生产了第"+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 Coke{
int id;//产品编号
public Coke(int id){
this.id=id;
}
}
//缓冲区
class SynContainer{
//需要一个容器大小
Coke[] cokes=new Coke[10];
//容器计数器
int count=0;
//生产者放入产品
public synchronized void push(Coke coke){
//如果容器满了,就需要等待消费者消费
if(count== cokes.length){
//通知消费者消费,生产等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果容器没有满,生产产品
cokes[count]=coke;
count++;
//通知消费者
this.notify();
}
//消费者消费产品
public synchronized Coke pop(){
//如果没有产品消费
if(count==0){
//等待生产者生产,等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果有产品消费
count--;
Coke coke=cokes[count];
//消费完了,通知生产者生产
this.notify();
return coke;
}
}
运行结果:
②信号灯法
源代码:
package cn.ecut.pc;
//解决方式二:信号灯法
public class TestPC2 {
public static void main(String[] args) {
Tv tv=new Tv();
new Actor(tv).start();
new Audience(tv).start();
}
}
//生产者(演员)
class Actor extends Thread{
Tv tv;
public Actor(Tv tv){
this.tv=tv;
}
@Override
public void run() {
for (int i = 1; i < 20; i++) {
if(i%2==0){
this.tv.play("迪迦奥特曼");
}else{
this.tv.play("泰罗奥特曼");
}
}
}
}
//消费者(观众)
class Audience extends Thread{
Tv tv;
public Audience(Tv tv){
this.tv=tv;
}
@Override
public void run() {
for (int i = 1; i < 20; i++) {
tv.watch();
}
}
}
//产品(节目)
class Tv{
//演员表演,观众等待。观众观看,演员等待。
String voice;//表演的节目
boolean flag=true;//标志位
//表演
public synchronized void play(String voice){
//如果观众没看完,演员等待
if(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果观众看完了,演员表演
System.out.println("演员表演了:"+voice);
//表演完了,通知观众观看
this.notifyAll();
this.voice=voice;//更新
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;
}
}
运行结果:
③线程池
源代码:
package cn.ecut.pc;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestPool {
public static void main(String[] args) {
//1.创建线程池
ExecutorService service= Executors.newFixedThreadPool(10);
//2.执行
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
//3.关闭连接
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
运行结果: