为了回忆一下J2SE中的线程互斥与同步问题,所以今天就写个生产者与消费者问题。这个程序大部分时间的结果都基本正确,但某些时候会造成死锁。百思不得其解,将代码贴上,方便以后有更深的体会时再进行修改。也方便各位同学借鉴与指正。
代码如下:
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author passzh
* 2010.11.7 10:30pm
* the problem of producter and consumer
*/
public class ProductAndConsumer {
public static void main(String[] args)
{
MyFun my=new MyFun();
}
}
class MyFun
{
//设置signal
static Integer empty=4;
static Integer full=0;
static Integer matrix=1;
//被挂起的线程的队列
ArrayList list_p=new ArrayList();
ArrayList list_c=new ArrayList();
public MyFun()
{
Producter[] producter=new Producter[4];
Consumer[] consumer=new Consumer[4];
for(int i=0;i<4;i++)
{
producter[i]=new Producter(i);
consumer[i]=new Consumer(i);
producter[i].start();
consumer[i].start();
}
}
//定义PV操作
public void p(MyThread mythread,int tag)
{
//tag==1是为生产者,为2时是消费者
if(tag==1)
{
synchronized(MyFun.empty)
{
MyFun.empty--;
//System.out.println("p操作empty="+MyFun.empty);
}
if(MyFun.empty<0)
{
try {
synchronized(mythread)
{
//String name=tag==1?"生产者":"消费者";
System.out.println("生产者"+mythread.getNo()+"被挂起");
list_p.add(mythread);
mythread.wait();
}
} catch (InterruptedException ex) {
Logger.getLogger(ProductAndConsumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
else if(tag==2)
{
synchronized(MyFun.full)
{
MyFun.full--;
//System.out.println("p操作full="+MyFun.full);
}
if(MyFun.full<0)
{
try {
synchronized(mythread)
{
//String name=tag==1?"生产者":"消费者";
System.out.println("消费者"+mythread.getNo()+"被挂起");
list_c.add(mythread);
mythread.wait();
}
} catch (InterruptedException ex) {
Logger.getLogger(ProductAndConsumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
//定义V操作
public void v(int tag)
{
if(tag==1)
{
synchronized(MyFun.full)
{
MyFun.full++;
//System.out.println("v操作full="+MyFun.full);
}
if(MyFun.full<=0)
{
//System.out.println();
if(list_c.size()>0)
{
MyThread thr=list_c.get(0);
synchronized(thr)
{
list_c.remove(0);
thr.notify();
System.out.println("消费者"+thr.getNo()+"被唤醒");
}
}
}
}
else if(tag==2)
{
synchronized(MyFun.empty)
{
MyFun.empty++;
//System.out.println("v操作empty="+MyFun.empty);
}
if(MyFun.empty<=0)
{
if(list_p.size()>0)
{
MyThread thr=list_p.get(0);
synchronized(thr)
{
list_p.remove(0);
thr.notify();
System.out.println("生产者"+thr.getNo()+"被唤醒");
}
}
}
}
}
class MyThread extends Thread
{
protected int no;
public int getNo()
{
return this.no;
}
}
class Producter extends MyThread
{
public Producter(int n)
{
this.no=n;
}
public void run()
{
synchronized(this)
{
p(this,1);
System.out.println("生产者"+this.getNo()+"生产一个产品");
v(1);
}
}
}
class Consumer extends MyThread
{
public Consumer(int n)
{
this.no=n;
}
public void run()
{
synchronized(this)
{
p(this,2);
System.out.println("消费"+this.getNo()+"消费一个产品");
v(2);
}
}
}
}
and result:
result 1:
生产者0生产一个产品
生产者1生产一个产品
消费0消费一个产品
消费1消费一个产品
生产者2生产一个产品
生产者3生产一个产品
消费2消费一个产品
消费3消费一个产品
result2:
生产者0生产一个产品消费1消费一个产品消费者0被挂起生产者1生产一个产品消费者0被唤醒消费0消费一个产品消费者2被挂起消费者3被挂起生产者2生产一个产品消费者2被唤醒消费2消费一个产品生产者3生产一个产品消费者3被唤醒消费3消费一个产品