package practice; |
/** |
* @说明: 生产者和消费者问题 |
* |
* 生产者(Productor)将产品交给店员(Clerk),而消费者(Consumer)从店员处 |
取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图 |
生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通 |
知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如 |
果店中有产品了再通知消费者来取走产品。 |
这里可能出现两个问题: |
生产者比消费者快时,消费者会漏掉一些数据没有取到。 |
消费者比生产者快时,消费者会取相同的数据。 |
* |
* 分析:多线程 —— 生产者、消费者 |
* 线程安全 —— 产品数量(或店员) |
* 线程通信 —— 产品过多:生产者wait();产品过少:消费者wait() |
* |
* |
* @作者: 帅哥哥 |
* @日期: 2021年08月22日 16:15 |
*/ |
public class ThreadCommunications { |
public static void main(String[] args) { |
Clerk clerk = new Clerk(); |
Productor p = new Productor(clerk); |
Consumer c = new Consumer(clerk); |
p.setName( "生产者" ); |
c.setName( "消费者" ); |
p.start(); |
c.start(); |
} |
} |
//店员 |
class Clerk{ |
private int apple = 0 ; |
//生产产品 |
public synchronized void produc(){ |
//synchronized (this){ |
//notify(); |
if (apple < 20 ){ |
apple++; |
System.out.println(Thread.currentThread().getName() + "开始生产第" + apple + "个产品" ); |
notify(); //当生产一个产品就可以唤醒消费者进行消费 |
} else { |
try { |
wait(); |
} catch (InterruptedException e) { |
e.printStackTrace(); |
} |
} |
} |
//消费产品 |
public synchronized void consum() { |
//synchronized (this){ |
//notify(); |
if (apple > 0 ){ |
System.out.println(Thread.currentThread().getName() + "开始消费第" + apple + "个产品" ); |
apple--; |
notify(); //每消费一个产品就可以唤醒生产者进行生产 |
} else { |
try { |
wait(); |
} catch (InterruptedException e) { |
e.printStackTrace(); |
} |
} |
} |
} |
//生产者 |
class Productor extends Thread{ |
private Clerk clerk; |
public Productor(Clerk clerk) { |
this .clerk = clerk; |
} |
@Override |
public void run() { |
while ( true ){ |
//System.out.println(getName() + "开始生产产品..."); |
|
clerk.produc(); |
|
} |
} |
} |
//消费者 |
class Consumer extends Thread{ |
private Clerk clerk; |
public Consumer(Clerk clerk) { |
this .clerk = clerk; |
} |
@Override |
public void run() { |
while ( true ){ |
//System.out.println(getName()+"开始消费产品..."); |
|
clerk.consum(); |
|
} |
|
} |
} |