Java语言描述经典同步问题
来源:互联网 发布:校园广播系统 杰网络 编辑:程序博客网 时间:2024/05/05 16:25
1 生产者-消费者问题
生产者-消费者(producer-consumer)问题也就是有界缓冲区(bounded-buffer)问题,即生产者不断的往有界缓冲区中放产品,消费者不断从中取产品,在保证两者互斥的基础上,当缓冲区满时生产者要阻塞,等待消费者取产品后将其唤醒,当缓冲区空时消费者要阻塞,等待生产者放产品后将其唤醒。用Java信号量描述的算法如下:
//互斥信号量
Semaphoremutex =new Semaphore(1);
//空缓冲区数量
Semaphoreempty = new Semaphore(BUFFER_SIZE);
//满缓冲区数量
Semaphorefull = new Semaphore(0);
// producer calls this method
public void insert(Object item) {
empty.acquire();
mutex.acquire();
//add an item to the buffer
buffer[in] = item;
in= (in + 1) % BUFFER_SIZE;
mutex.release();
full.release(); }
// consumer calls this method
public Object remove() {
full.acquire();
mutex.acquire();
//remove an item from the buffer
Object item = buffer[out];
out= (out + 1) % BUFFER_SIZE;
mutex.release();
empty.release();
return item; }
分别创建生产者线程和消费者线程调用相应方法,在程序运行正确后,可调换互斥信号量与资源信号量的位置,学生即可观察到死锁的发生。用Java的synchronized同步锁或ReentrantLock锁也可描述该算法,但传统低级别的API较难使用,易导致程序结构混乱和性能问题,因此Java语言提供了BlockingQueue接口,使得同步操作完全对用户透明。BlockingQueue接口的实现类有ArrayBlockingQueue、LinkedBlockingQueue和PriorityBlockingQueue三种,以ArrayBlockingQueue为例描述生产者-消费者问题的算法如下:
ArrayBlockingQueue<Integer>buffer =
newArrayBlockingQueue<Integer>(BUFFER_SIZE);
// A task for adding an int to the buffer
while (true) {
try{
buffer.put(i++); // Add any value tothe buffer
}catch (InterruptedException ex) { } }
// A task for reading and deleting an intfrom the buffer
while (true) {
try{
buffer.take();
}catch (InterruptedException ex) { } }
通过BlockingQueue接口的使用,使学生看到,随着技术的发展,并发程序设计将会变得更加简单而且逐步普及,从而建立起学习进程管理的信心和兴趣。
2 读者-写者问题
读者-写者(Reader-Writer)是保证一个Writer线程必须与其他线程互斥的访问共享对象的同步问题。用Java信号量描述的算法如下:
intreaderCount = 0;
Semaphoremutex = new Semaphore(1);
Semaphorewriter = new Semaphore(1);
//writer thread
writer.acquire();
//writing is performed
writer.release();
//reader thread
mutex.acquire();
readerCount++;
if(readerCount == 1)
writer.acquire();
mutex.release();
//reading is performed
mutex.acquire();
readerCount--;
if(readerCount == 0)
writer.release();
mutex.release();
同样可用Java的synchronized同步锁或ReentrantLock锁描述该算法,但Java语言提供的ReentrantReadWriteLock类使得读者-写者问题的编程更为简单,且其比synchronized同步锁具有更高的并发性能,算法如下:
ReentrantReadWriteLockrwl =
newReentrantReadWriteLock();
//Extract read and write locks
LockreadLock = rwl.readLock();
LockwriteLock = rwl.writeLock();
//Use the read lock in all accessors:
readLock.lock();
try { . . . }
finally { readLock.unlock(); }
//Use the write lock in all mutators:
writeLock.lock();
try { . . . }
finally { writeLock.unlock(); }
修改ReentrantReadWriteLock类的构造方法,可分别实现写者优先和读者优先算法,简单的修改代码,学生便可直观的观测到两种策略的不同结果。
3 哲学家进餐问题
由Dijkstra引入的哲学家进餐问题是需要在多个线程之间分配多个资源且不会出现死锁和饥饿形式的简单表示[3]。用Java信号量描述的算法如下:
Semaphore[]chopStick = new Semaphore[5];
for(int i=0; i<5; i++)
chopStick[i] = new Semaphore(1);
while (true) {
//get left chopstick
chopStick[i].acquire();
//get right chopstick
chopStick[(i+1) % 5].acquire();
eating();
//return left chopstick
chopStick[i].release();
chopStick[(i+1) % 5].release();
thinking();
}
学生可运行并修改程序以观察死锁和饥饿问题,然后对其改进以解决死锁和饥饿问题。通过运行真实的代码,学生就有了真实的经验,传统的伪语言或动画模拟是无法达到该效果的。
- Java语言描述经典同步问题
- JAVA中经典同步问题
- java同步经典问题生产者消费者
- 经典进程同步问题
- 经典进程同步问题
- 经典进程同步问题
- java语言简短描述
- 二叉排序树-java语言描述
- Java语言描述:回溯法之最小重量机器问题
- Java语言描述:回溯法之最优装载问题
- Java语言描述:分支限界法之01背包问题
- Java语言描述:动态规划法之编辑距离问题
- 经典线程同步问题(生产者&消费者)--Java实现
- Java经典线程同步问题------生产者与消费者
- 经典线程同步问题(生产者&消费者)--Java实现
- Java 多线程同步问题的探究-经典讲解
- Java经典线程同步问题------生产者与消费者
- 经典C语言教程-存在错误描述
- 电脑重装了请问怎样找回好友的聊天记录呢
- Linux ——usb触摸屏驱动 - usbtouchscreen
- WifiChat即时聊天应用源码
- CUICatalog: Invalid asset name supplied:
- js中(function(){…})()立即执行函数写法理解
- Java语言描述经典同步问题
- 维基实体相关度计算 笔记
- JsonKit简单使用
- socket 编程概要
- 基数排序简介及其并行化
- 【ECSHOP二次开发】:入门(序言)
- .NET 3.x新特性之Lambda表达式
- 安装maven以及给myeclipse安装m2eclipse插件
- ros(robot operating system机器人操作系统)订阅函数的多线程使用方法(C++: 外部变量控制跳出for循环)