• Java硬件同步机制Swap指令模拟+记录型信号量模拟


    实验存档//。。 

    以生产者消费者问题作为背景。

    进程同步方式接口:

    package method;
    
    /**
     *  P表示通过,V表示释放
     */
    public interface Method {
        void p();
        void v();
    }

    模拟 Swap 指令实现该接口:

    package method;
    
    public class Swap implements Method {
        private boolean lock = false;
        /**
         * 创建一个特殊的instance变量(它得是一个对象)来充当锁
         */
        private byte[] objectLock = new byte[0];
    
        public void p() {
            boolean key = true;
            boolean temp;
            do {
                synchronized(objectLock) {
                    temp = key;
                    key = lock;
                    lock = temp;
                }
            } while (key != false);
        }
    
        public void v(){
            synchronized (objectLock) {
                this.lock = false;
            }
        }
    }

    生产者 & 消费者:

    package entity.producerconsumer;
    
    import method.Method;
    
    /**
     * 生产者实体类
     */
    public class Producer implements Runnable {
        /**
         * 统计生产者数量
         */
        private static int total = 0;
        /**
         * 生产者个体的 id
         */
        private int id;
        /**
         * 模拟缓冲区
         */
        private Buffer buffer;
        /**
         * 允许动态更改同步机制
         */
        private Method method;
    
        /**
         * 传入缓冲区地址,同步机制
         * @param buffer
         * @param method
         */
        public Producer(Buffer buffer, Method method) {
            this.id = ++total;
            this.buffer = buffer;
            this.method = method;
        }
    
        /**
         * 打印生产者信息
         * @return
         */
        @Override
        public String toString() {
            return id + " 号生产者";
        }
    
        @Override
        public void run() {
            while (true) {
                method.p();
                // 临界区代码
                if (buffer.notFull()) {
                    // 生产产品
                    buffer.putItem();
                    System.out.println(this  + ": " + buffer);
                }
    
                method.v();
            }
        }
    }

    /

    package entity.producerconsumer;
    
    import method.Method;
    
    /**
     * 消费者实体类
     */
    public class Consumer implements Runnable {
        /**
         * 统计消费者数量
         */
        private static int total = 0;
        /**
         * 消费者个体的 id
         */
        private int id;
        /**
         * 模拟缓冲区
         */
        private Buffer buffer;
        /**
         * 允许动态更改同步机制
         */
        private Method method;
    
        /**
         * 传入缓冲区地址,同步机制
         * @param buffer
         * @param method
         */
        public Consumer(Buffer buffer, Method method) {
            this.id = ++total;
            this.buffer = buffer;
            this.method = method;
        }
    
        /**
         * 打印消费者信息
         * @return
         */
        @Override
        public String toString() {
            return id + " 号消费者";
        }
    
        @Override
        public void run() {
            while (true) {
                method.p();
                // 临界区代码
                if (buffer.notEmpty()) {
                    // 消费产品
                    buffer.getItem();
                    System.out.println(this  + ": " + buffer);
                }
    
                method.v();
            }
        }
    }

    /

    package entity.producerconsumer;
    
    /**
     * 缓冲区实体,用于模拟缓冲区
     */
    public class Buffer {
        /**
         * 当前产品数量
         */
        private int count = 0;
        /**
         * 最大允许数量
         */
        private int max;
    
        public Buffer(int max) {
            this.max = max;
        }
    
        /**
         * 判断缓冲区是否为满
         * @return
         */
        public boolean notFull() {
            return (count < max);
        }
    
        /**
         * 判断缓冲区是否为空
         * @return
         */
        public boolean notEmpty() {
            return (count > 0);
        }
    
        /**
         * 生产产品
         */
        public void putItem() {
            count++;
        }
    
        /**
         * 消费产品
         */
        public void getItem() {
            count--;
        }
    
        /**
         * 打印缓冲区信息
         * @return
         */
        @Override
        public String toString() {
            return "缓冲区内有 " + count + " 件产品";
        }
    }

    用于测试 Swap 指令的主函数:

    package test;
    
    import entity.producerconsumer.Buffer;
    import entity.producerconsumer.Consumer;
    import entity.producerconsumer.Producer;
    import method.Method;
    import method.Swap;
    
    public class Main {
        public static void main(String[] args) {
            // 缓冲区大小为 10
            Buffer buffer = new Buffer(10);
            // 允许动态更改同步机制
            Method SynchronizationMechanism = new Swap();
            // 创建 5 个生产者和 5 个消费者
            for (int i = 0; i != 5; ++i) {
                new Thread(new Producer(buffer, SynchronizationMechanism)).start();
                new Thread(new Consumer(buffer, SynchronizationMechanism)).start();
            }
        }
    }

    用记录型信号量重新实现接口(此段代码来自课件):

    package method;
    
    /*
        该类用于模拟信号量及其P,V操作
        使用方法如下:
    
        method.Semaphore mutex = new method.Semaphore(1);            //信号量的初值赋为1
        mutex.p();
        //临界区代码
        mutex.v();
    */
    
    public class Semaphore implements Method {
        private int semValue;
        public Semaphore(int semValue) {
            this.semValue = semValue;
        }
        public synchronized void p() {
            semValue--;
            if (semValue < 0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public synchronized void v(){
            semValue++;
            if (semValue <= 0) {
                this.notify();
            }
        }
    }
  • 相关阅读:
    字符串拼接练习
    java数字字符的全半角转化
    mysql 的group by 满足的规则要求:
    从指定字符串获取n个随机数
    jQuery去除空格的$.trim()
    mysql里的位运算小结
    sql的case 用法
    泛型之元组示例
    jQuery里的replaceAll和replaceWith
    根据索引条件查询结果与原表关联的查询
  • 原文地址:https://www.cnblogs.com/xkxf/p/7866956.html
Copyright © 2020-2023  润新知