日常小结-经典IPC问题实现

26 篇文章 0 订阅
11 篇文章 0 订阅

基本原理来自《现代操作系统》我用java给重写了一边。多线程经验不多,有问题多指教。

生产者消费者问题

有一点需要特别注意一下,如果只有一个生产者一个消费者可以使用notify。如果有多个生产者和消费者则需要使用notifyall否则会产生死锁。
这里使用wait和notify方法实现也可以使用其他方式。日后或许会在补充。

package ipc;

import java.util.Random;

public class ProductorandConsumerWithWait {

    static final int N = 10;
    static final productor p1 = new productor();
    static final productor p2 = new productor();
    static final consumer c = new consumer();
    static final monitor mon = new monitor();

    public static void main(String[] args) {
        p1.start();
        p2.start();
        c.start();
    }
    static class productor extends Thread{

        @Override
        public void run(){
            int item;
            while(true){
                item = productor_item();
                mon.insert(item);
            }
        }

        private int productor_item() {
            Random random = new Random();
            int item = random.nextInt();
            System.out.println("生产 :"+item);
            return item;
        }
    }

    static class consumer extends Thread{

        @Override
        public void run(){
            int item;
            while(true){
                item = mon.remove();
                consum_item(item);
            }
        }

        private void consum_item(int item) {
            System.out.println("消费 :"+item);
        }
    }

    static class monitor{
        private int[] buffer = new int[N];
        private int count = 0, lo = 0, hi = 0;

        public synchronized void insert(int val){
            if(count == N)
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            buffer[hi] = val;
            hi = (hi+1)/N;
            count = count +1;
            if(count == 1) notifyAll();
        }

        public synchronized int remove(){
            if(count ==0)
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            int val = buffer[lo];
            lo = (lo+1)/N;
            count--;
            if(count == N-1) notifyAll();
            return val;
        }
    }
}

哲学家就餐

没有特别需要注意的。原书中是使用互斥锁,如果使用java中间的lock应该更符合原意,这里使用的是synchronized不过就目前来看效果是一样的。

package ipc;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class PhilosopherDining {

    static final private int THINKING = 0;
    static final private int HUNGRY = 1; 
    static final private int EATING = 2;

    static final private int NUMBER = 5;
    int[] state = new int[NUMBER];
    private Semaphore[] s = new Semaphore[NUMBER];

    public void takeforks(int i){
        take_forks(i);
        try {
            s[i].acquire();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            s[i].release();
        }
    }

    private synchronized void take_forks(int i){
        state[i] = HUNGRY;
        test(i);
    }

    public synchronized void put_forks(int i ){
        state[i] = THINKING;
        test((i+NUMBER-1)%NUMBER);
        test((i+1)%NUMBER);
    }

    private void test(int i){
        if(state[i] == HUNGRY && state[(i+NUMBER-1)%NUMBER] != EATING && state[(i+1)%NUMBER] != EATING){
            state[i] = EATING;
            System.out.println("Philosopher "+i+" is having dinner!");
            s[i].release();
        }
    }

    public static void main(String[] args) {
        PhilosopherDining pd = new PhilosopherDining();
        for(int i = 0 ; i< NUMBER ; i++){
            pd.s[i] = new Semaphore(1);
        }
        ExecutorService pool = Executors.newFixedThreadPool(5);
        for(int i = 0 ;i < NUMBER ; i++){
            Runner runner = new Runner(pd,i);
            pool.submit(runner);
        }       
    }


}
package ipc;

public class Runner implements Runnable{


        private PhilosopherDining ph;
        private int i;
        public Runner(PhilosopherDining ph,int i){
            this.ph = ph;
            this.i = i;
        }

        @Override
        public void run() {
            while(true){
                ph.takeforks(i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                ph.put_forks(i);
            }
        }

}

读者写者问题

java中有专门的读写类。如果使用ReentrantReadWriteLock,应该更科学一些。以后会在补充。

package ipc;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class ReaderandWriter {

    Semaphore db = new Semaphore(1);
    int rc = 0;
    Semaphore hasWriter = new Semaphore(1);

    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(7);
        ReaderandWriter rw = new ReaderandWriter();

        Reader r1 = new Reader(rw);
        Reader r2 = new Reader(rw);
        Reader r3 = new Reader(rw);
        Reader r4 = new Reader(rw);
        Reader r5 = new Reader(rw);
        Writer w1 = new Writer(rw);
        Writer w2 = new Writer(rw);
        pool.submit(r1);
        pool.submit(r2);
        pool.submit(r3);
        pool.submit(r4);
        pool.submit(r5);
        pool.submit(w1);
        pool.submit(w2);


    }

}
package ipc;

public class Reader implements Runnable{
        private ReaderandWriter rw;

        public Reader(ReaderandWriter rw) {
            this.rw = rw;
        }

        @Override
        public void run() {
            while(true){
                try {
                addrc();
                System.out.println(rw.rc + "is reading");
                Thread.sleep(1);
                cutrc();
                System.out.println(rw.rc+"use data");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        private  void cutrc() {
            synchronized (rw) {
                rw.rc--;
                if(rw.rc == 0){
                    rw.db.release();
                }           
            }

        }

        private  void addrc() throws InterruptedException {
            synchronized (rw) {
                if(!rw.hasWriter.tryAcquire()){
                    rw.db.release();
                    rw.hasWriter.acquire();
                    rw.db.acquire();

                }
                rw.rc++;
                if(rw.rc ==1){
                        rw.db.acquire();
                }
                rw.hasWriter.release();         
            }

        }
}
package ipc;

public class Writer implements Runnable{
        private ReaderandWriter rw;
        public Writer(ReaderandWriter rw){
            this.rw = rw;
        }

        @Override
        public void run() {
            while(true){
                try {
                    rw.hasWriter.acquire();
                    System.out.println("think up data");
                    Thread.sleep(1);
                    rw.db.acquire();
                    System.out.println("write data base");
                    rw.db.release();
                    rw.hasWriter.release();
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值