java实现的PV操作经典例子:读者写者、贪睡的理发师、生产者消费者。

    技术2023-10-13  65

    其中读者写者和贪睡的理发师使用的Semaphore类;生产者消费者使用的是管程。

    读者写者

    class Semaphore { int value; public Semaphore(int v) { this.value = v; } public synchronized void p() { value -= 1; if (value < 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized void v() { value += 1; if (value <= 0) { this.notify(); } } } class Reader implements Runnable { int count; Semaphore rmutex; Semaphore wmutex; public Reader(int c, Semaphore r, Semaphore w) { this.count = c; this.rmutex = r; this.wmutex = w; } public void run() { while (true) { rmutex.p(); if (count == 0) { wmutex.p(); System.out.println("****************************reader has got lock no writer is allowed*************************"); System.out.println("ReaderReaderReaderReader Thread: " + Thread.currentThread().getName() + " current count= " + count); } count++; rmutex.v(); System.out.println("I AM Reader: " + Thread.currentThread().getName() + " count= " + count + " I am DOING SOME JOB!"); try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } rmutex.p(); count--; System.out.println("I AM Reader: " + Thread.currentThread().getName() + " count= " + count + " I am quiting work"); if (count == 0) { // System.out.println( // "ReaderReaderReaderReader Thread: " + Thread.currentThread().getName() + "give up lock"); wmutex.v(); System.out.println("****************************readers all give up lock*************************"); System.out.println(); } rmutex.v(); try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Writer implements Runnable { Semaphore wmutex; public Writer(Semaphore w) { this.wmutex = w; } public void run() { while (true) { wmutex.p(); System.out.println("====================writer has got lock no reader is allowed==================================="); System.out.println("WriterWriterWriter Thread: " + Thread.currentThread().getName()); System.out.println("begin writting data..."); try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("finish writting data."); wmutex.v(); System.out.println("=======================================writer give up lock=========================================="); System.out.println(); } } } public class ReaderWriter { public static void main(String[] args) { int count = 0; Semaphore rmutex = new Semaphore(1); Semaphore wmutex = new Semaphore(1); Reader reader = new Reader(count, rmutex, wmutex); Writer writer = new Writer(wmutex); Thread r1 = new Thread(reader); Thread r2 = new Thread(reader); Thread w1 = new Thread(writer); Thread w2 = new Thread(writer); w1.start(); r1.start(); w2.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } r2.start(); } }

    贪睡的理发师

    class Semaphore{ int value; public Semaphore(int v) { this.value = v; } public synchronized void p() { value--; if(value < 0) { try { wait(); }catch(InterruptedException e) { e.printStackTrace(); } } } public synchronized void v() { value++; if(value <= 0) { notifyAll(); } } } class Customer implements Runnable{ Semaphore mutex; Semaphore customer; Semaphore barber; int index; public Customer(int index, Semaphore mutex, Semaphore customer, Semaphore barber) { this.index = index; this.mutex = mutex; this.customer = customer; this.barber = barber; } public void run() { mutex.p(); if(BC.count >= BC.MAX) { System.out.println("椅子已经坐满,顾客" + index + " 离开"); mutex.v(); }else { BC.count++; customer.v(); // 通知理发师等待理发人数加1 mutex.v(); barber.p(); // 抢夺理发师 System.out.println("顾客" + index + " 开始理发"); // System.out.println("顾客: " + Thread.currentThread().getName().toString() + " 正在理发"); } } } class Barbe implements Runnable{ Semaphore mutex; Semaphore customer; Semaphore barber; public Barbe(Semaphore mutex, Semaphore customer, Semaphore barber) { this.mutex = mutex; this.customer = customer; this.barber = barber; } public void run() { while(true) { customer.p(); mutex.p(); BC.count--; barber.v(); mutex.v(); System.out.println(" 理发师理发"); try { Thread.sleep((long)(Math.random() * 1000)); }catch(InterruptedException e) { e.printStackTrace(); } } } } public class BC{ static int count; static int MAX = 5; static Semaphore mutex = new Semaphore(1); static Semaphore barber = new Semaphore(1); static Semaphore customer = new Semaphore(0); public static void main(String[] args) { Barbe bar = new Barbe(mutex, customer, barber); Thread b1 = new Thread(bar); b1.start(); int n = 10; for(int i=0;i<n;i++) { Customer cus = new Customer(i, mutex, customer, barber); Thread t = new Thread(cus); t.start(); System.out.println("顾客: " + i + " 等待理发"); try { Thread.sleep((long)(Math.random() * 2000)); }catch(InterruptedException e) { e.printStackTrace(); } } } }

    监控器实现的是生产者消费者

    什么是监控器?

    监控器每次只能由一个线程访问;对共享变量的访问只能发生在监控器内定义的过程中。

    import java.util.Vector; class CP{ Vector pool; int product = 0; // 产品数量 public static int EMPTY = 0; public static int FULL = 25; public CP() { pool = new Vector(); } public synchronized void produce() { try { if(pool.size() == FULL) wait(); product++; pool.addElement(new Integer(product)); // 把产品放到产品池中 System.out.println("Produce: " + product); if(pool.size() == EMPTY + 1) notify(); }catch(InterruptedException e) { e.printStackTrace(); } } public synchronized void consume() { try { if(pool.size() == EMPTY) wait(); System.out.println("Consume: " + pool.firstElement().toString()); pool.removeElementAt(0); if(pool.size() == FULL - 1) notify(); }catch(InterruptedException e) { e.printStackTrace(); } } } class Producer extends Thread{ CP cp; public Producer(CP cp) { super(); this.cp = cp; } public void run() { while(true) { cp.produce(); //模拟做其他工作 try { Thread.sleep((long)(Math.random()* 1000)); }catch(InterruptedException e) { e.printStackTrace(); } } } } class Consumer extends Thread{ CP cp; public Consumer(CP cp) { super(); this.cp = cp; } public void run() { while(true) { cp.consume(); //模拟做其他事情 try { Thread.sleep((long)(Math.random() * 1000)); }catch(InterruptedException e) { e.printStackTrace(); } } } } public class ProducerConsumer{ public static void main(String[] args) { CP cp = new CP(); Producer producer = new Producer(cp); Consumer consumer = new Consumer(cp); producer.start(); consumer.start(); } }

     

    Processed: 0.035, SQL: 9