JAVA多线程生产者和消费者问题的两种写法(一种出错了)

时间:2022-01-06 17:31:03
[size=24px]希望大神指点

//这个代码是正确的    同步锁是Clerk这个类的对象的this指针  方法放在Clerk这个类  相当于资源类    把生产和消费全都放在了
Clerk类中


public class Test {
  public static void main(String[] args) {
Clerk clerk=new Clerk();
Pro p=new Pro(clerk);
Runnable c=new Consumer(clerk);  
Thread t1=new Thread(p);
Thread t2=new Thread(c);
t1.start();
t2.start();
}
}

class Clerk
{
int product;

public synchronized  void addProduct() {
if(product>=20)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
product++;

System.out.println(Thread.currentThread().getName()+"生产了第"+product+"个产品");
notify();
}
}

public synchronized void comsumer() {
if(product<=0)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{

System.out.println(Thread.currentThread().getName()+"消费了第"+product+"个产品");
product--;
notify();
}
}
}

class Pro implements Runnable
{
Clerk clerk;

public Pro(Clerk clerk)
{
this.clerk=clerk;
}

public void run() {
System.out.println("生产者开始生产产品");
while(true)
{
clerk.addProduct();
}
}
}

class Consumer implements Runnable{
Clerk clerk;
public Consumer(Clerk clerk)
{
this.clerk=clerk;
}
public void run() {
System.out.println("消费者开始消费产品");
while(true)
{
clerk.comsumer();
}
}



}


//但是我换了一个思路  把添加产品和消费产品放在了生产者和消费者类中,然后产品个数只是在资源类中,以资源类的那个对象作为同步锁  结果程序炸了
//生产者消费者问题
//发生异常的程序
public class PruducerAndCustomerTest {
      public static void main(String[] args) {
  Resource resource=new Resource();
  Runnable producer=new Producer(resource);
  Runnable customer=new Customer(resource);
 
  Thread t1=new Thread(producer);
  Thread t2=new Thread(customer);
  
  t2.start();
  t1.start();
}
}

class Producer implements Runnable
{  
private Resource resource;

public Producer(Resource r)
{
this.resource=r;
}
    
public void run() {
while(true)
{
synchronized (resource) 
{  
try {
Thread.sleep(50);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (resource.product >=50) 
{
try 
{
wait();

catch (InterruptedException e) 
{
// TODO Auto-generated catch block
e.printStackTrace();
}


else {
resource.product++;
System.out.println("生产了第" + resource.product + "个产品");
notifyAll();
     }
}
}


}



}

class Customer implements Runnable
{
   private Resource resource;
  
public Customer(Resource r)
{
this.resource=r;
}
public void run() {
while(true)


 synchronized (resource) 
   {
if (resource.product <= 0)
{
try 
{
wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else 
{
System.out.println("消费了第" + resource.product + "个产品");
resource.product--;
notifyAll();
}
    }
}
   

}
   

}



class Resource
{
public int product=50;

}

[/size]

3 个解决方案

#1


 class PruducerAndCustomerTest {
      public static void main(String[] args) {
          Resource resource=new Resource();
          Runnable producer=new Producer(resource);
          Runnable customer=new Customer(resource);
          
          Thread t1=new Thread(producer);
          Thread t2=new Thread(customer);
           
          t2.start();
          t1.start();
    }
}
 
class Producer implements Runnable
{  
    private Resource resource;
     
    public Producer(Resource r)
    {
        this.resource=r;
    }
    public void run() {
        while(true)
        {
            synchronized (resource) 
            {  
               /* try {
                    Thread.sleep();
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }*/
                if (resource.product >=50) 
                {
                    try 
                    {
                        resource.wait();
                    } 
                    catch (InterruptedException e) 
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } 
                else {
                    resource.product++;
                    System.out.println(Thread.currentThread().getName()+"生产了第" + resource.product + "个产品");
                    resource.notifyAll();
                     }
            }
        }
    }
}
class Customer implements Runnable
{
   private Resource resource;
   
    public Customer(Resource r)
    {
        this.resource=r;
    }
    public void run() {
        while(true)
        { 
                 
         synchronized (resource) 
               {
                if (resource.product <= 0)
                {
                    try 
                    {
                        resource.wait();
                    } catch (InterruptedException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                else 
                {
                    System.out.println(Thread.currentThread().getName()+"消费了第" + resource.product + "个产品");
                    resource.product--;
                    resource.notifyAll();
                }
            }
    }
    }
}
class Resource
{
    public int product=50;
     }
//  如果不是有多条生产者线程和多条消费者线程  用notify()就可以的   当然只是我的见解

#2


IllegalStateException是说没有获得当前Obj的锁
修改方式有点反直觉,wait()的对象不是Producer或者Customer, 而是resource

public class ProducerAndCustomerTest {
    public static void main(String[] args) {
        Resource resource=new Resource();
        Runnable producer=new Producer(resource);
        Runnable customer=new Customer(resource);
        
        Thread t1=new Thread(producer);
        Thread t2=new Thread(customer);
         
        t2.start();
        t1.start();
       
        
  }
}

class Producer implements Runnable
{  
  private Resource resource;
  boolean overLimit = false; 
  public Producer(Resource r)
  {
      this.resource=r;
  }
   
  public void run() {
      while(true)
      {
       synchronized (resource) 
          {  
              try {
                  Thread.sleep(50);
              } catch (InterruptedException e1) {
                 
              }
              if (resource.product >=50) 
              {
                 try 
                  {
                      resource.wait();
                  } 
                  catch (InterruptedException e) 
                  {
                     
                  }
              }else {
                  resource.product++;
                  System.out.println("生产了第" + resource.product + "个产品");
                  resource.notify();
              }
          }
       
      }
       
       
  }


   
}

class Customer implements Runnable
{
 private Resource resource;
 boolean hasProduction = false;
  public Customer(Resource r)
  {
      this.resource=r;
  }
  public void run() {
      while(true)
      { 
               
       synchronized (resource) 
             {
              if (resource.product <= 0)
              {
               try 
                  {
                       resource.wait();
                  } catch (InterruptedException e)
                  {
                      
                  }
              }
              else 
              {
               System.out.println("消费了第" + resource.product + "个产品");
                  resource.product--;
                  resource.notify();
              }
          }
       
  }
      
   
  }
      

}
   


class Resource
{
  public int product=50;
   
}



#3


wait( );  notify( );前面要加resource.

#1


 class PruducerAndCustomerTest {
      public static void main(String[] args) {
          Resource resource=new Resource();
          Runnable producer=new Producer(resource);
          Runnable customer=new Customer(resource);
          
          Thread t1=new Thread(producer);
          Thread t2=new Thread(customer);
           
          t2.start();
          t1.start();
    }
}
 
class Producer implements Runnable
{  
    private Resource resource;
     
    public Producer(Resource r)
    {
        this.resource=r;
    }
    public void run() {
        while(true)
        {
            synchronized (resource) 
            {  
               /* try {
                    Thread.sleep();
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }*/
                if (resource.product >=50) 
                {
                    try 
                    {
                        resource.wait();
                    } 
                    catch (InterruptedException e) 
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } 
                else {
                    resource.product++;
                    System.out.println(Thread.currentThread().getName()+"生产了第" + resource.product + "个产品");
                    resource.notifyAll();
                     }
            }
        }
    }
}
class Customer implements Runnable
{
   private Resource resource;
   
    public Customer(Resource r)
    {
        this.resource=r;
    }
    public void run() {
        while(true)
        { 
                 
         synchronized (resource) 
               {
                if (resource.product <= 0)
                {
                    try 
                    {
                        resource.wait();
                    } catch (InterruptedException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                else 
                {
                    System.out.println(Thread.currentThread().getName()+"消费了第" + resource.product + "个产品");
                    resource.product--;
                    resource.notifyAll();
                }
            }
    }
    }
}
class Resource
{
    public int product=50;
     }
//  如果不是有多条生产者线程和多条消费者线程  用notify()就可以的   当然只是我的见解

#2


IllegalStateException是说没有获得当前Obj的锁
修改方式有点反直觉,wait()的对象不是Producer或者Customer, 而是resource

public class ProducerAndCustomerTest {
    public static void main(String[] args) {
        Resource resource=new Resource();
        Runnable producer=new Producer(resource);
        Runnable customer=new Customer(resource);
        
        Thread t1=new Thread(producer);
        Thread t2=new Thread(customer);
         
        t2.start();
        t1.start();
       
        
  }
}

class Producer implements Runnable
{  
  private Resource resource;
  boolean overLimit = false; 
  public Producer(Resource r)
  {
      this.resource=r;
  }
   
  public void run() {
      while(true)
      {
       synchronized (resource) 
          {  
              try {
                  Thread.sleep(50);
              } catch (InterruptedException e1) {
                 
              }
              if (resource.product >=50) 
              {
                 try 
                  {
                      resource.wait();
                  } 
                  catch (InterruptedException e) 
                  {
                     
                  }
              }else {
                  resource.product++;
                  System.out.println("生产了第" + resource.product + "个产品");
                  resource.notify();
              }
          }
       
      }
       
       
  }


   
}

class Customer implements Runnable
{
 private Resource resource;
 boolean hasProduction = false;
  public Customer(Resource r)
  {
      this.resource=r;
  }
  public void run() {
      while(true)
      { 
               
       synchronized (resource) 
             {
              if (resource.product <= 0)
              {
               try 
                  {
                       resource.wait();
                  } catch (InterruptedException e)
                  {
                      
                  }
              }
              else 
              {
               System.out.println("消费了第" + resource.product + "个产品");
                  resource.product--;
                  resource.notify();
              }
          }
       
  }
      
   
  }
      

}
   


class Resource
{
  public int product=50;
   
}



#3


wait( );  notify( );前面要加resource.