做为操做系统中的最基本模型,在面试中被要求书写的可能性仍是很大的,若是只是伪码,这仍是一个简单的问题,可是要你具体实现呢?你会使用什么样的方式来实现这件事情呢?java
什么是生产者、消费者问题?面试
// 变量
list = buffer[n] // 生产链,容量为n
,mutex = 1 // 互斥使用生产链
,empty = n // 消费后剩余
,full = 0 // 生产后容量
// 两个运做对象:及对应动做
producer:product // 生产者生产
consumer:consume // 消费者消费
// 两个动做
product{
wait(empty) // 生产链不满
wait(mutex)
// 生产
signal(mutex)
signal(full) // 给生产链加一个产品
}
consumer{
wait(full) // 生产链不为空
wait(mutex)
// 消费
signal(mutex)
signal(empty) // 生产链中的产品又被消耗
}
复制代码
class ProducerAndConsumer {
private final int MAX_LEN = 10;
private Queue<Integer> queue = new LinkedList<Integer>();
Semaphore producer = new Semaphore(0);
Semaphore consumer = new Semaphore(MAX_LEN);
Semaphore lock = new Semaphore(1);
// 生产者
class Producer extends Thread {
@Override
public void run() {
while (true) {
try {
consumer.acquire(); // 可消费的数量未满
lock.acquire(); // 临界区
queue.add(1);
System.out.println("consumer size:" + queue.size());
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.release();
producer.release();
}
}
}
}
// 消费者
class Consumer extends Thread {
@Override
public void run() {
while (true) {
try {
producer.acquire(); // 还剩余产品
lock.acquire(); // 临界区
queue.remove();
System.out.println("consumer size:" + queue.size());
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.release();
consumer.release();
}
}
}
}
public static void main(String[] args) {
ProducerAndConsumer producerAndConsumer = new ProducerAndConsumer();
Producer producer = producerAndConsumer.new Producer();
Consumer consumer = producerAndConsumer.new Consumer();
producer.start();
consumer.start();
}
}
复制代码
五把叉子,五我的,若是每一个人都拿起了叉子,那么整桌的人必然就没饭吃了,哲学家问题思考的就是这样的一个问题。bash
// 变量
forks = {1, 1, 1, 1, 1} // 暂定为5人
// 一个被运做对象:以及动做
fork:handle、release
Philosopher:thinking、eating
// 动做,eating和thinking是两个Thread.sleep完成
handle {
// 左右手只要有一只被拿起,就须要等待
// 若是不等带,就可能每一个人只拿一只
while(forks[postion] == 0 || forks[(position + 1) % 5] == 0){
wait() // 等待
}
forks[postion] == 0;
forks[(position + 1) % 5] == 0;
}
release {
// 吃完之后把东西放下
forks[postion] == 1;
forks[(position + 1) % 5] == 1;
}
复制代码
public class PhilosopherEat {
class Philosopher extends Thread {
private String name;
private Fork fork;
public Philosopher(String name, Fork fork) {
super(name);
this.name = name;
this.fork = fork;
}
@Override
public void run() {
// 哲学家须要完成要的一系列动做
while (true) {
thinking();
fork.takeFork();
eating();
fork.putFork();
}
}
public void eating() {
System.out.println("I am Eating:" + name);
try {
//模拟吃饭
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void thinking() {
System.out.println("I am Thinking:" + name);
try {
//模拟思考
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Fork{
// 5根筷子
private boolean[] used={false,false,false,false,false,false};
public synchronized void takeFork(){
String name = Thread.currentThread().getName();
int i = Integer.parseInt(name);
// 若是左右手有一只正被使用就等待
while(used[i]||used[(i+1)%5]){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
used[i ]= true;
used[(i+1)%5]=true;
}
// 同时释放左右手的筷子
public synchronized void putFork(){
String name = Thread.currentThread().getName();
int i = Integer.parseInt(name);
used[i ]= false;
used[(i+1)%5]=false;
notifyAll();
}
}
public static void main(String[] args) {
PhilosopherEat philosopher = new PhilosopherEat();
Fork fork = philosopher.new Fork();
philosopher.new Philosopher("0",fork).start();
philosopher.new Philosopher("1",fork).start();
philosopher.new Philosopher("2",fork).start();
philosopher.new Philosopher("3",fork).start();
philosopher.new Philosopher("4",fork).start();
}
}
复制代码
读者写者问题针对的就是咱们的数据问题,你在wps
打开一个文件,又在word
打开一个文件势必会看到一个只读的模式会弹出,这就是读者写着问题的具体表现了。ide
// 变量
readCount // 当前读书的人数
,readLock // 读者锁
,writeLock // 写者锁
// 两个对象:及其动做
Reader:read
Writer:write
// 动做
read{
p(readLock)
if(readCount == 0) p(writeLock) // 第一个读者进入后,就不可修改
readCount++
v(readLock)
// 。。。读书
p(readLock)
readCount--
if(readCount == 0) v(writeLock) // 最后一个读者走后,能够开始修改
v(readLock)
}
write{
p(writeLock)
// 。。。修改
v(writeLock)
}
复制代码
import java.util.concurrent.Semaphore;
public class ReaderAndWriter {
public static void main(String[] args) {
// 实现写者与写者间、读者与写者间互斥
Semaphore wmutex = new Semaphore(1);
// 用于改变 readCount 变量时实现互斥
Semaphore rmutex = new Semaphore(1);
for (int i = 0; i < 3; ++i) {
new Reader(rmutex, wmutex).start();
new Writer(wmutex).start();
}
}
}
class Reader extends Thread {
private static int total = 0;
private int id;
private Semaphore rmutex, wmutex;
private static int readCount = 0;
public Reader(Semaphore rmutex, Semaphore wmutex) {
id = ++total;
this.rmutex = rmutex;
this.wmutex = wmutex;
}
@Override
public void run() {
while (true) {
try {
rmutex.acquire();
// 只有第一个读者进程须要执行 wmutex.p()
if (readCount == 0) wmutex.acquire();
readCount++;
System.out.println(id + " 号读者在读");
} catch (Exception e) {
} finally {
rmutex.release();
}
// 模拟读书
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 读书人出去了
try {
rmutex.acquire();
readCount--;
System.out.println(id + " 号读者结束阅读:当前还剩 " + readCount + " 位读者在读");
if (readCount == 0) wmutex.release();
} catch (Exception e) {
} finally {
rmutex.release();
}
}
}
}
class Writer extends Thread {
private static int total = 0;
private int id;
private Semaphore wmutex;
public Writer(Semaphore wmutex) {
id = ++total;
this.wmutex = wmutex;
}
@Override
public void run() {
while (true) {
try {
wmutex.acquire();
// 执行写操做
System.out.println(id + " 号写者正在写");
wmutex.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 线程休眠一段时间,总不会一直改的
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
复制代码
以上就是个人学习成果,若是有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。post
相关文章推荐:学习