JAVA多线程生产者与消费者问题昨天看了一下资料,模仿着写了个,怎么跑起来死锁了?望各位大牛看看哪代码有误 ?
正确的情况 应该是 ,打印 生产 一个 ,接着打印 消费一个 (假设最多只能存放一个产品)/**
* 店员类
* 假设 店内只有一个产品架 只能存放一个产品
*
*
*/
public class Clerk { //-1代表店内没有可用产品
private int product = -1;
//生产一个产品
public synchronized void setProduct(int product) throws InterruptedException{
if(this.product != -1){
//产品架上还有产品 等待消费者消费
wait();
}
this.product = product;
System.out.println("当前线程"+Thread.currentThread().getName()+"生产第"+product+"个产品");
//解锁 并通知其他线程进入线程等待队列排队
notify();
}
//消费一个产品
public synchronized void getProduct(int product) {
if(this.product == -1){
//没有产品 等待生产者生产
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.product = -1;
System.out.println("当前线程"+Thread.currentThread().getName()+"消费第"+product+"个产品");
//解锁 并通知其他线程进入线程等待队列排队
notify();
}
}/**
* 生产者
*
*
*/
public class Produce implements Runnable { private Clerk clerk;
public void run(){
for(int i=1; i<=10; i++){
if(this.clerk == null){
clerk = new Clerk();
}
System.out.println("----当前线程"+Thread.currentThread().getName()+ "开始生产");
try {
clerk.setProduct(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}/**
* 消费者
*
*
*/
public class Consume implements Runnable { private Clerk clerk;
public void run(){
for(int i=1; i<=10; i++){
if(this.clerk == null){
clerk = new Clerk();
}
System.out.println("----当前线程"+Thread.currentThread().getName()+ "开始消费");
try {
clerk.getProduct(i);
} catch (Exception e) {
e.printStackTrace();
};
}
}
}//调用类
public class Main { public static void main(String[] args){
Produce pro = new Produce();
Thread produceThread = new Thread(pro);
produceThread.start();
Consume con = new Consume();
Thread consumeThread = new Thread(con);
consumeThread.start();
}
}
正确的情况 应该是 ,打印 生产 一个 ,接着打印 消费一个 (假设最多只能存放一个产品)/**
* 店员类
* 假设 店内只有一个产品架 只能存放一个产品
*
*
*/
public class Clerk { //-1代表店内没有可用产品
private int product = -1;
//生产一个产品
public synchronized void setProduct(int product) throws InterruptedException{
if(this.product != -1){
//产品架上还有产品 等待消费者消费
wait();
}
this.product = product;
System.out.println("当前线程"+Thread.currentThread().getName()+"生产第"+product+"个产品");
//解锁 并通知其他线程进入线程等待队列排队
notify();
}
//消费一个产品
public synchronized void getProduct(int product) {
if(this.product == -1){
//没有产品 等待生产者生产
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.product = -1;
System.out.println("当前线程"+Thread.currentThread().getName()+"消费第"+product+"个产品");
//解锁 并通知其他线程进入线程等待队列排队
notify();
}
}/**
* 生产者
*
*
*/
public class Produce implements Runnable { private Clerk clerk;
public void run(){
for(int i=1; i<=10; i++){
if(this.clerk == null){
clerk = new Clerk();
}
System.out.println("----当前线程"+Thread.currentThread().getName()+ "开始生产");
try {
clerk.setProduct(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}/**
* 消费者
*
*
*/
public class Consume implements Runnable { private Clerk clerk;
public void run(){
for(int i=1; i<=10; i++){
if(this.clerk == null){
clerk = new Clerk();
}
System.out.println("----当前线程"+Thread.currentThread().getName()+ "开始消费");
try {
clerk.getProduct(i);
} catch (Exception e) {
e.printStackTrace();
};
}
}
}//调用类
public class Main { public static void main(String[] args){
Produce pro = new Produce();
Thread produceThread = new Thread(pro);
produceThread.start();
Consume con = new Consume();
Thread consumeThread = new Thread(con);
consumeThread.start();
}
}
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(p).start();
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[] arrWT = new WoTou[6];
public synchronized void push(WoTou wt) {
while(index == arrWT.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
arrWT[index] = wt;
index ++;
}
public synchronized WoTou pop() {
while(index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
index--;
return arrWT[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 wt = new WoTou(i);
ss.push(wt);
System.out.println("生产了:" + wt);
try {
Thread.sleep((int)(Math.random() * 200));
} 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 wt = ss.pop();
System.out.println("消费了: " + wt);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//调用类
public class Main { public static void main(String[] args) {
//生产者和消费者公用一个clerk,通过构造函数分别给其传值
Clerk clerk = new Clerk();
Produce pro = new Produce(clerk);
Thread produceThread = new Thread(pro);
produceThread.start(); Consume con = new Consume(clerk);
Thread consumeThread = new Thread(con);
consumeThread.start(); }
}/**
* 消费者
*
*
*/
public class Consume implements Runnable { private Clerk clerk;
public Consume(Clerk clerk) {
this.clerk = clerk;
} public void run() {
for (int i = 1; i <= 10; i++) {
if (this.clerk == null) {
clerk = new Clerk();
}
System.out.println("----当前线程" + Thread.currentThread().getName()
+ "开始消费");
try {
clerk.getProduct(i);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}/**
* 生产者
*
*
*/
public class Produce implements Runnable { private Clerk clerk;
public Produce(Clerk clerk) {
this.clerk = clerk;
} public void run() {
for (int i = 1; i <= 10; i++) {
if (this.clerk == null) {
clerk = new Clerk();
}
System.out.println("----当前线程" + Thread.currentThread().getName()
+ "开始生产");
try {
clerk.setProduct(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}/**
* 店员类 假设 店内只有一个产品架 只能存放一个产品
*
*
*/
public class Clerk { // -1代表店内没有可用产品
private int product = -1; // 生产一个产品
public synchronized void setProduct(int product)
throws InterruptedException { if (this.product != -1) {
// 产品架上还有产品 等待消费者消费
wait();
}
this.product = product;
System.out.println("当前线程" + Thread.currentThread().getName() + "生产第"
+ product + "个产品");
// 解锁 并通知其他线程进入线程等待队列排队
notify();
} // 消费一个产品
public synchronized void getProduct(int product) { if (this.product == -1) {
// 没有产品 等待生产者生产
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.product = -1;
System.out.println("当前线程" + Thread.currentThread().getName() + "消费第"
+ product + "个产品");
// 解锁 并通知其他线程进入线程等待队列排队
notify();
}
}
注意main方法我修改的部分 以及2个线程对象的构造方法.修改后2个线程共享同一资源
/**
* 店员类 假设 店内只有一个产品架 只能存放一个产品
*
*
*/
class Clerk { // -1代表店内没有可用产品
private int product = -1; // 生产一个产品
public synchronized void setProduct(int product)
throws InterruptedException { if (this.product != -1) {
// 产品架上还有产品 等待消费者消费
wait();
}
this.product = product;
System.out.println("当前线程" + Thread.currentThread().getName() + "生产第"
+ product + "个产品");
// 解锁 并通知其他线程进入线程等待队列排队
notify();
} // 消费一个产品
public synchronized void getProduct(int product) { if (this.product == -1) {
// 没有产品 等待生产者生产
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.product = -1;
System.out.println("当前线程" + Thread.currentThread().getName() + "消费第"
+ product + "个产品");
// 解锁 并通知其他线程进入线程等待队列排队
notify();
}
}/**
* 生产者
*
*
*/
class Produce implements Runnable { private Clerk clerk; public Produce(Clerk c){
this.clerk = c;
}
public void run() {
for (int i = 1; i <= 10; i++) {
/*if (this.clerk == null) {
clerk = new Clerk();
}*/
System.out.println("----当前线程" + Thread.currentThread().getName()
+ "开始生产");
try {
clerk.setProduct(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}/**
* 消费者
*
*
*/
class Consume implements Runnable {
private Clerk clerk;
public Consume(Clerk c){
this.clerk= c;
} public void run() {
for (int i = 1; i <= 10; i++) {
/*if (this.clerk == null) {
clerk = new Clerk();
}*/
System.out.println("----当前线程" + Thread.currentThread().getName()
+ "开始消费");
try {
clerk.getProduct(i);
} catch (Exception e) {
e.printStackTrace();
}
;
}
}
}// 调用类
public class Main { public static void main(String[] args) {
Clerk c = new Clerk();
Produce pro = new Produce(c);
Thread produceThread = new Thread(pro);
produceThread.start(); Consume con = new Consume(c);
Thread consumeThread = new Thread(con);
consumeThread.start(); }
}