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();
        }
    }
}

 

posted @ 2017-11-20 16:36  xkfx  阅读(1090)  评论(0编辑  收藏  举报