线程 - 生产者消费者问题、哲学家问题、读者写者问题、理发师问题

生产者消费者问题

m个生产者和n个消费者 共享k个缓冲池区的循环缓冲池
生产者不能从一个空缓冲区中取产品,生产者不能向一个已装满的缓冲池投放产品

public class ProducerAndConsumer {

   private static final int k = 10;

   private static int cons = 0;

   private static int[] buffer = new int[k];

   private static int in = 0;

   private static int out = 0;

   private static int num = 0;

   private static int nums = 100;

   private static Lock mutex = new ReentrantLock();

   private static Condition emptyLock = mutex.newCondition();

   private static Condition fullLock = mutex.newCondition();

   public static void produce() throws InterruptedException{
       do {
           mutex.lock();
           try {
               if (cons >= k) fullLock.await();
               num++;
               buffer[in] = num;
               in = (in + 1) % k;
               cons++;
               System.out.println("produce : cons = " + cons);
               if (cons > 0) emptyLock.signal();
           }finally {
               mutex.unlock();
           }
           /**
            * produce
            * wait(empty)
            * wait(mutex)
            * buffer(in) = num;
            * in = (in+1) mod k
            * signal(mutex)
            * signal(full)
            */
       }while (num < nums);
   }

   public static void consumer() throws InterruptedException{
       do {
           mutex.lock();
           try {
               if (cons <= 0) emptyLock.await();
               System.out.println("get " + buffer[out]);
               buffer[out] = -1;
               out = (out + 1) % k;
               cons--;
               System.out.println("consumer : cons = " + cons);
               if (cons < k) fullLock.signal();
           } finally {
               mutex.unlock();
           }
           /**
            * wait(full)
            * wait(mutex)
            * num = buffer(out);
            * out = (out+1) mod k
            * signal(mutex)
            * signal(empty)
            * consumer
            */
       }while (num <= nums);
   }
}

/**
* @Test
*     public void ProducerAndConsumerTest() throws Exception{
*         Thread t1 = new Thread(new Producer());
*         Thread t2 = new Thread(new Consumer());
*         t1.start();
*         t2.start();
*         t1.join();
*         t2.join();
*     }
*
*     private class Producer implements Runnable {
*         public void run() {
*             try {
*                 ProducerAndConsumer.produce();
*             } catch (Exception e) {
*                 e.printStackTrace();
*             }
*         }
*     }
*
*     private class Consumer implements Runnable {
*         public void run() {
*             try {
*                 ProducerAndConsumer.consumer();
*             } catch (Exception e) {
*                 e.printStackTrace();
*             }
*         }
*     }
* */

读者写者问题

任意多个Reader可以读 只能有一个Writer可以写 写的时候不能读
public class ReaderAndWriter {

   private static int text = 0;

   private static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

   public static void read() {
       try {
           rwl.readLock().lock();
           Thread.sleep(300);
           System.out.println("read " + text);
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           rwl.readLock().unlock();
       }
   }

   public static void write() {
       try {
           rwl.writeLock().lock();
           int num = (int) (Math.random() * 1000);
           System.out.println("writing");
           text = num;
           Thread.sleep(2000);
           System.out.println("write " + num);
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           rwl.writeLock().unlock();
       }
   }
}

/**
* private class Writer implements Runnable {
*         public void run() {
*             while (true)
*                 if(((int)(Math.random()*100000))%3333 == ((int)(Math.random()*100000))%3333)
*                     ReaderAndWriter.write();
*         }
*     }
*
*     private class Reader implements Runnable {
*         public void run() {
*             while (true)
*                 ReaderAndWriter.read();
*         }
*     }
*
*     @Test
*     public void ReaderAndWriterTest() throws Exception{
*         Thread[] readerThreads = new Thread[4];
*         Thread[] writerThreads = new Thread[2];
*
*         for (int i = 0; i < 2; i++) {
*             writerThreads[i] = new Thread(new Writer());
*             writerThreads[i].start();
*         }
*
*         for (int i = 0; i < 4; i++) {
*             readerThreads[i] = new Thread(new Reader());
*             readerThreads[i].start();
*         }
*
*         for (int i = 0; i < 4; i++) {
*             writerThreads[i].join();
*         }
*
*         for (int i = 0; i < 2; i++) {
*             writerThreads[i].join();
*         }
*
*     }
* */

哲学家问题

平时哲学家围坐在圆桌交替进行思考和进餐,饥饿时试图分别取两侧筷子,只有两只筷子都拿到后才能进餐
死锁解决:
1.限制最多拿筷子的哲学家数量,至少保证一个哲学家拿到两个筷子
2.只有左右筷子都可拿时才允许拿
3.规定奇数先取左侧偶数先取右侧

public class Philosopher implements Runnable{

    private int times = 20;

    private final int philosophers = 3;

    private int id;

    private int left;

    private int right;

    private Lock lock; //= new ReentrantLock();

    private Condition[] locks;// = new Condition[philosophers];

    private boolean[] chop;// = new boolean[philosophers];

    Philosopher(int id,Lock lock,Condition[] conditions,boolean[] chop) {
        this.lock = lock;
        this.locks = conditions;
        this.chop = chop;
        this.id = id;
        this.left = id;
        this.right = (id+1) % philosophers;
    }

    private void eating() throws InterruptedException{
        lock.lock();
        try {
            while(!chop[left] || !chop[right]) {
                System.out.println(id + "等待筷子");
                locks[id].await();
            }
            chop[left] = false;
            chop[right] = false;
        } finally {
            lock.unlock();
        }
        System.out.println(id+"开始吃饭");
        Thread.sleep(1000);
    }

    private void sleeping() throws InterruptedException{
        lock.lock();
        try {
            chop[left] = true;
            chop[right] = true;
            System.out.println(id + "开始睡觉");
            if(chop[(left+philosophers-1) % philosophers]) locks[(left+philosophers-1)%philosophers].signal();
            if(chop[(right+1) % philosophers]) locks[(right+1) % philosophers].signal();
        } finally {
            lock.unlock();
        }
        Thread.sleep(1000);
    }

    public void run() {
        try {
            while (times >= 0) {
                eating();
                sleeping();
                times--;
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

理发师问题

一位理发师、一把理发椅、n把等候椅

第一个顾客叫醒理发师,后来的若有空位则等待
没有顾客时理发师睡觉

public class BarberShop {

    private static final int MAX_CUSTOMER = 3;

    private static int waiting = 0;

    private static Lock lock = new ReentrantLock();

    private static Condition cust_ready = lock.newCondition(); //理发椅是否有顾客

    private static boolean is_cust_ready = false;

    private static Condition finished = lock.newCondition();   //是否完成理发

    private static Lock mutex = new ReentrantLock(); //互斥访问waiting

    private static Lock chair = new ReentrantLock();  //椅子是否空闲

    private static void cut_hair() {
        System.out.println("开始理发");
    }

    private static void exit_barbershop(int i) {
        System.out.println("当前人数:" + waiting + " "+ i +" 离开理发店");
    }

    private static void sit_in_chair(int i) {
        System.out.println(i + "在等待椅坐下");
    }

    private static void stand_from_chair(int i) {
        System.out.println(i + "从椅子站起");
    }
    public static void barber () {
        lock.lock();
        try {
            while (true) {
                if(!is_cust_ready) {
                    System.out.println("等待顾客");
                    cust_ready.await();
                }
                cut_hair();
                Thread.sleep(1000);
                is_cust_ready = false;
                finished.signal();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        /**
         * do {
         *  wait(cust_ready);
         *  cut_hair;
         *  signal(finished);
         * }while(1);
         * */
    }

    public static void customer(int i) {
        mutex.lock();
        if (waiting < MAX_CUSTOMER) {
            waiting = waiting + 1;
            mutex.unlock();
        } else {
            mutex.unlock();
            exit_barbershop(i);
            return;
        }
        chair.lock();
        sit_in_chair(i);
        mutex.lock();
        waiting = waiting + 1;
        mutex.unlock();
        lock.lock();
        try {
            is_cust_ready = true;
            cust_ready.signal();
            finished.await();
            stand_from_chair(i);
            waiting = waiting - 1;
            chair.unlock();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        /**
         * wait(mutex);
         * if(waiting < n) {
         *  waiting = waiting +1;
         *  signal(mutex);
         * } else {
         *  signal(mutex)
         *  exit_barbershop
         *  return;
         * }
         * wait(chair)
         * sit_in_chair
         * wait(mutex)
         * waiting = waiting -1
         * signal(mutex)
         * signal(cust_ready)
         * get_haircut
         * wait(finished)
         * stand_from_chair
         * signal(chair)
         * */
    }
}

/**
 * private static class Barber implements Runnable{
 *         public void run() {
 *             BarberShop.barber();
 *         }
 *     }
 *
 *     private static class Customer implements Runnable {
 *
 *         private int i;
 *
 *         public Customer(int i) {
 *             this.i = i;
 *         }
 *
 *         public void run() {
 *             BarberShop.customer(i);
 *         }
 *     }
 *
 *     @Test
 *     public void  barber() throws Exception{
 *         Thread[] customers = new Thread[10];
 *         Thread t1 = new Thread(new Barber());
 *         t1.start();
 *         for (int i = 0; i < 10; i++) {
 *             int time = (int)(Math.random() * 1000);
 *             Thread.sleep(time);
 *             customers[i] = new Thread(new Customer(i));
 *             customers[i].start();
 *         }
 *         for (int i = 0; i < 10; i++) {
 *             customers[i].join();
 *         }
 *         t1.join();
 *     }
 * */

猜你喜欢

转载自blog.csdn.net/qq_37873426/article/details/89418654