java實現的PV操作經典例子:讀者寫者、貪睡的理髮師、生產者消費者。

其中讀者寫者和貪睡的理髮師使用的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();
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章