学校实验存档//。。

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

进程同步方式接口:

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

最新文章

  1. POJ 2559 Largest Rectangle in a Histogram
  2. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
  3. CodeForces Round #280 (Div.2)
  4. hashTable(哈希表)的基本用法
  5. KALI 2.0优化
  6. Data Types in the Kernel &amp;lt;LDD3 学习笔记&amp;gt;
  7. Css3 常见鼠标滑过效果集合
  8. mysql 5.6 设置慢查询
  9. redis 缓存技术与memcache的最大差别
  10. [ffmpeg] h.264解码所用的主要缓冲区介绍
  11. SfMLearner 记录
  12. JAVA的第二次作业
  13. 如何调用layer.open打开的的iframe窗口中的JS
  14. github上的面试库
  15. pt-table-checksum 使用方法【转】
  16. EOS的发币逻辑
  17. IP工具类
  18. Linux sed 命令字符串替换使用方法详解
  19. 在Postgresql中添加新角色(Role)
  20. 使用Java语言开发微信公众平台(八)——自定义菜单功能

热门文章

  1. Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3
  2. 简介Objective-C语言
  3. EXSI5.5以上开启KVM二次虚拟化
  4. jsp+servlet+mvc模式图
  5. JavaScript json和字符串互转
  6. 使用arc进行code review
  7. lua获取table的长度
  8. golang 中的定时器(timer),更巧妙的处理timeout
  9. 简明python教程九----异常
  10. C++学习笔记-类相关问题总结