甚至,奇怪和偶然的消费者 - 生产者

时间:2015-10-15 14:27:43

标签: java multithreading buffer semaphore producer-consumer

我想在这里做的是甚至消费者打印偶数,奇数消费者打出奇数。

evenodd方法基本上消耗任何数字和打印(无论是偶数还是奇数)。我有2个even个消费者线程,2个odd个消费者线程,2个evenodd个消费者线程和3个producer个线程。

我是信号量概念的新手,我尝试过使用它。当我删除evenodd方法和相关的线程时,我得到正确的输出,即偶数数字偶数线程数和奇数线程奇数数字。但是,当我再次使用evenodd方法和evenodd线程时,我遇到了僵局。

如果有人可以指导我,我会出错,以及如何解决这个问题,那将会非常有帮助。请详细说明如何实现evenodd方法以使其正常工作。

package lab61;

import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.Semaphore;

public class Process {

    Semaphore empty;
    Semaphore full;
    Semaphore even;
    Semaphore odd;
    Semaphore mutex;
    //Semaphore evenodd;
    boolean evenb;
    boolean oddb,eo;

    LinkedList<Integer> list;
    Random random;


    public Process(int capacity){
            list=new LinkedList<Integer>();

            empty=new Semaphore(capacity);

            full=new Semaphore(0,true);
            mutex=new Semaphore(1,true);

            even=new Semaphore(0,true);
            evenb=false;
            oddb=false;
            eo=false;

            odd=new Semaphore(0,true);
            //evenodd = new Semaphore(0,true);

            random=new Random();
    }

    public void Producer() throws InterruptedException{

        while(true){

        int a=random.nextInt(100);  

        empty.acquire();
        mutex.acquire();

            list.add(a);
            System.out.println("Producing "+a);
            System.out.println(list);



            if((list.get(0)%2)==0){
                if(!evenb){
                 even.release();
                evenb = true;
                }
            }else if((list.get(0)%2)==1){
                if(!oddb){
                 odd.release();
                oddb = true;
                }


            }
            /*if(((list.get(0)%2)==0)||((list.get(0)%2)==1)){
                if(!eo){
                    evenodd.release();
                    eo = true;
                }
            }*/


        mutex.release();


        full.release();


        }

    }

  public void consumereven() throws InterruptedException{
      while(true){
      //Thread.sleep(2000);
          even.acquire();
          Thread.sleep(2000);
          full.acquire();

          mutex.acquire();

            int value = list.removeFirst();
            System.out.println("I am the even consumer "+ value);
            evenb = false;
            System.out.println(list);

          mutex.release();
          empty.release();

      }

  }


  public void consumerodd() throws InterruptedException{
      while(true){

          //Thread.sleep(2000);
          odd.acquire();
          Thread.sleep(2000);
          full.acquire();
          //odd.acquire();
          mutex.acquire();
            int value = list.removeFirst();
            System.out.println("I am the odd consumer "+ value);
            System.out.println(list);
          oddb = false;
          mutex.release();
          empty.release();

      }

  } 
 public void evenodd() throws InterruptedException {
      while(true){

          full.acquire();
          mutex.acquire();
          int value = list.removeFirst();
          System.out.println("i am the evenodd consumer " + value );

          if((list.get(0)%2)==0){
              if(oddb=true){
                  odd.acquire();
                  oddb=false;
              }
              if(evenb==false){
                  even.release();
                  evenb = true;
              }
          }
          else if((list.get(0)%2)==1){
              if(evenb=true){
                  even.acquire();
                  evenb=false;
              }
              if(oddb==false){
                  odd.release();
                  oddb = true;
              }
          }
          System.out.println(list);


          mutex.release();
          empty.release();
      }
  }



    }
package lab61;

import lab6.producer;

public class App {


    public static void main(String[] args) throws InterruptedException{

        Process p=new Process(10);


        Thread producer1=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.Producer();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });


        Thread producer2=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.Producer();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });

        Thread producer3=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.Producer();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });



        Thread consumereven1=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.consumereven();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



            }
        });

Thread consumereven2=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.consumereven();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



            }
        });

Thread consumerodd1=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.consumerodd();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



            }
        });
Thread consumerodd2=new Thread(new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            p.consumerodd();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }
});
Thread evenodd1=new Thread(new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            p.evenodd();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }
});
Thread evenodd2=new Thread(new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            p.evenodd();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }
});


        producer1.start();
        producer2.start();
        producer3.start();
        consumereven1.start();
        consumereven2.start();
        consumerodd1.start();
        consumerodd2.start();
        evenodd1.start();
        evenodd2.start();

        producer1.join();
        producer2.join();
        producer3.join();
        consumereven1.join();
        consumereven2.join();
        consumerodd1.join();
        consumerodd2.join();
        evenodd1.join();
        evenodd2.join();

    }





}

2 个答案:

答案 0 :(得分:1)

代码可能导致死锁,因为consumereven()consumerodd()方法在evenodd信号量之前获取fullmutex信号量,evenodd()方法在fullmutex信号量之前获取evenodd信号量。这导致一种情况,例如,运行consumereven()的线程具有even信号量但在等待full信号量时被阻塞,而运行evenodd()的线程具有{full信号量。 1}}信号量,但在even信号量上被阻塞,因此两个线程都已死锁。

为了帮助防止死锁,当您使用多个锁时,最好始终以相同的顺序获取它们,并以相反的顺序释放它们。

答案 1 :(得分:0)

这不是一个好方法,但你可以做类似的事情。

import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.Semaphore;

public class P1 {

    Semaphore empty;
    Semaphore full;
    Semaphore even;
    Semaphore odd;
    Semaphore mutex;
    Semaphore oddeven;

    LinkedList<Integer> list;
    Random random;
    boolean oddb;
    boolean evenb; 
    boolean oddevenb;

    public P1(int capacity){
            list=new LinkedList<Integer>();

            empty=new Semaphore(capacity,true);

            full=new Semaphore(0,true);

            mutex=new Semaphore(1,true);

            even=new Semaphore(0,true);

            odd=new Semaphore(0,true);

            oddeven=new Semaphore(0,true);

            oddb=false;
            evenb=false;
            oddevenb = false;

            random=new Random();
    }

    public void Producer(String s) throws InterruptedException{

        while(true){

        int a=random.nextInt(100);  

        empty.acquire();
        mutex.acquire();

            list.add(a);

            System.out.println("Producing "+a+" By "+s);
            System.out.println(list);
            int temp=random.nextInt(3)+1;

            if(temp==1  ){
                if(oddevenb==false){
                oddeven.release();
                oddevenb=true;
                evenb=true;
                oddb=true;
                }

            }

            else{
             if((list.get(0))%2==0){

                if(evenb==false){
                    even.release();
                    evenb=true;
                    oddevenb=true;
                }


            }else if((list.get(0))%2==1){


                    if( oddb==false) {
                    odd.release();
                    oddevenb=true;
                    oddb=true;

                }
            }       


            }



        mutex.release();
        full.release();


        }

    }

  public void consumereven(String s) throws InterruptedException{
      while(true){

         // Thread.sleep(5000);
          even.acquire();
          full.acquire();
          mutex.acquire();

            int value=list.removeFirst();
            System.out.println("I am the "+ s +" consumer "+value);
            evenb=false;
            oddevenb=false;
            System.out.println(list);

          mutex.release();
          empty.release();

      }

  }


  public void consumerodd(String s) throws InterruptedException{
      while(true){

          //Thread.sleep(5000);
          odd.acquire();
          full.acquire();
          mutex.acquire();

            int value=  list.removeFirst();;
            System.out.println("I am the "+s+"  consumer "+value);
            oddb=false;
            oddevenb=false;
            System.out.println(list);



          mutex.release();
          empty.release();

      }

  } 

  public void consumeroddeven(String s) throws InterruptedException{
      while(true){

          //Thread.sleep(5000);



          oddeven.acquire();
          full.acquire();
          mutex.acquire();

            int value=  list.removeFirst();;


            System.out.println("I am the  "+s+" "+value);

            System.out.println(list);
            oddevenb=false;
            evenb=false;
            oddb=false;

          mutex.release();
          empty.release();

      }

  }




}




public class App3 {


    public static void main(String[] args) throws InterruptedException{

        final P1 p=new P1(10);


        Thread producer=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.Producer("p1");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });


 Thread producer2=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.Producer("p2");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });

Thread producer3=new Thread(new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            p.Producer("p3");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
},"p3");




        Thread consumereven=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.consumereven("even1");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



            }
        });


        Thread consumereven2=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.consumereven("even2");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



            }
        });


Thread consumerodd=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.consumerodd("odd1");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



            }
        });


Thread consumerodd2=new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.consumerodd("odd2");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



            }
        });


Thread consumer=new Thread(new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            p.consumeroddeven("NC1");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }
});


Thread consumer1=new Thread(new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            p.consumeroddeven("NC2");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }
});

        producer.start();
        producer2.start();
        producer3.start();


        consumereven.start();
        consumereven2.start();

        consumerodd.start();
        consumerodd2.start();

        consumer.start();
        consumer1.start();


        producer.join();
        producer2.join();
        producer3.join();

        consumereven.join();
        consumereven.join();
        consumereven2.join();


        consumerodd.join();
        consumerodd.join();
        consumerodd2.join();


        consumer.join();
        consumer1.join();

    }





}