Semaphore 信号量,就是一个允许实现设置好的令牌。也许有1个,也许有10个或更多。
谁拿到令牌(acquire)就可以去执行了,如果没有令牌则需要等待。
执行完毕,一定要归还(release)令牌,否则令牌会被很快用光,别的线程就无法获得令牌而执行下去了。
请仔细体会里面关于仓库的处理,
1 是如何保证入库时,如果仓库满就等待,
2 出库时,如果仓库无货就等待的。
3 以及对仓库只有10个库位的处理。
4 对同步问题的处理。
package com.test.current;
import java.util.concurrent.Semaphore;
public class TestSemaphore {
public static void main(String[] args) {
for (int i = 0; i <= 3; i++) {
new Thread(new Producer()).start();
new Thread(new Consumer()).start();
}
}
//仓库
static WareHouse buffer = new WareHouse();
//生产者
static class Producer implements Runnable{
static int num = 1;
public void run() {
int n = num++;
while(true){
try{
buffer.put(n);
System.out.println(">"+n);
Thread.sleep(10);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Consumer implements Runnable{
public void run() {
while (true) {
try {
System.out.println("<"+buffer.take());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class WareHouse{
//非满锁
final Semaphore notFull = new Semaphore(10);
//非空锁
final Semaphore notEmpty = new Semaphore(0);
//互斥锁
final Semaphore mutex = new Semaphore(1);
//库存容量
final Object[] items = new Object[10];
int putPosi, takePosi, count;
public void put(Object x)throws InterruptedException{
try{
notFull.acquire();
mutex.acquire();
items[putPosi] = x;
if (++putPosi == items.length) {
putPosi = 0;
}
count++;
}finally{
notEmpty.release();
mutex.release();
}
}
public Object take()throws InterruptedException{
notEmpty.acquire();
mutex.acquire();
try{
Object x = items[takePosi];
if(++takePosi == items.length){
takePosi = 0;
}
--count;
return x;
}finally{
notFull.release();
mutex.release();
}
}
}
}
分享到:
相关推荐
a: 创建一个线程 b: 创建多个线程 c: 多线程访问同一资源 d: 经典线程同步互斥问题 e: 使用关键段解决子线程互斥问题 f: 利用事件实现线程同步问题 ...I: 信号量 semaphore 解决线程同步问题
总结来说,使用信号量实现有限缓冲区的生产者和消费者问题以及读进程具有优先权的读者和写者问题,关键在于正确地设计和操作信号量,确保并发进程的正确同步和互斥。在Linux下,C语言提供了丰富的接口支持信号量的...
通过信号量,可以确保缓冲区不满时生产者才能生产,缓冲区不空时消费者才能消费。 - **读者-写者问题**:多个读者可以同时读取数据,但写入时需要独占资源。使用信号量,可以实现多个读者同时读取,而写入时阻塞所有...
- 信号量机制:使用信号量控制生产者和消费者对缓冲区的互斥访问 - 生产者行为:生产产品时输出当前缓冲区的产品数量和位置 - 消费者行为:消费产品时输出当前缓冲区的产品数量和消费位置 - 多线程并发:通过多...
在生产者-消费者问题中,我们可以使用两个信号量:一个用于保护缓冲区的满/空状态(例如,设为buffer_size),另一个用于控制缓冲区中的产品数量(例如,设为count)。当缓冲区满时,生产者会阻塞直到count信号量有...
2. 信号量的实现:我们使用信号量来控制生产者和消费者的访问顺序。 3. 生产者线程的实现:我们实现了生产者线程的逻辑,包括生产数据和释放缓冲区的空闲信号量。 4. 消费者线程的实现:我们实现了消费者线程的逻辑...
在生产者-消费者模型中,可以设置一个信号量来控制队列的满和空状态,限制生产者的生产速率和消费者的消费速率。 7. **例程分析**:在提供的"生产者消费者"例程中,可能包含了创建生产者和消费者线程、初始化队列、...
总之,生产者消费者模式是多线程编程中的一种重要设计模式,它通过信号量和条件变量实现了线程间的同步和通信,有效提高了系统资源的利用率和整体效率。在Java中,我们可以借助并发库轻松实现这一模式,使得代码更加...
操作系统中的“生产者-消费者问题”是一个经典的多进程同步问题,它涉及到如何在共享资源有限的情况...通过深入理解信号量的工作原理以及其在生产者-消费者问题中的应用,我们可以更好地设计和优化多进程环境下的系统。
6. 示例程序:展示如何在用户空间使用新实现的信号量,模拟生产者消费者问题。 通过这个项目,开发者不仅可以深入理解信号量的工作原理,还能了解Linux内核中进程同步的实现细节。这有助于进一步学习和开发涉及多...
另一个是同步信号量,用于控制生产者和消费者的相对速度,确保缓冲区不会为空(供消费者消费)或满(供生产者生产)。 在`c_p.cpp`这个源代码文件中,我们可能看到以下的关键实现: 1. 初始化信号量: - 互斥信号...
操作系统中的生产者-消费者问题是进程同步的经典案例,它涉及到多个并发执行的进程(在这里是生产者和消费者)如何协作共享有限资源(有界缓冲池)的问题。在这个问题中,生产者进程负责生产消息并放入缓冲池,而...
在生产者-消费者问题中,可以使用互斥量(mutex)保证缓冲区的独占访问,以及使用条件变量(condition variable)实现生产者等待消费者消费或消费者等待生产者生产。 4. **互斥量**:互斥量用于实现对共享资源的...
多线程实现生产者消费者模型:锁(Lock)、信号量(Semaphore、BoundedSemaphore)、条件(Condition)、队列(Queue)、事件(Event) 多进程程实现生产者消费者模型:信号量(Semaphore)、条件(Condition)、...
生产者在放入数据前检查信号量,消费者在取出数据后更新信号量。 5. **CreateThread**: 用于创建新的线程。生产者和消费者线程就是通过这个函数创建的。 6. **ExitThread**: 当线程完成其工作时,使用此函数退出...
生产者线程在生成数据后增加信号量,消费者线程在消耗数据前等待信号量。 4. **消息队列(Message Queue)**:在生产者消费者模型中,通常会使用一个缓冲区作为数据交换的媒介。这个缓冲区可以看作是一个消息队列,...
生产者消费者模式基于操作系统提供的信号量(Semaphore)或管程(Monitor)等机制,以解决进程间的通信和同步问题。在这个模式中,生产者进程负责生成数据并放入缓冲区,而消费者进程则负责从缓冲区取出数据进行处理...
在给定的源代码中,应该详细展示了如何创建和使用这些信号量,以及如何在生产者和消费者进程中应用这些同步机制。 理解并能正确实施这种同步策略对于编写高效、可靠的多进程程序至关重要。这不仅有助于避免数据竞争...
3. **线程通信**:使用条件变量让线程在适当的时候被唤醒,如缓冲区有空位时唤醒生产者,或缓冲区有数据时唤醒消费者。 4. **性能优化**:考虑线程调度开销,避免不必要的上下文切换。 5. **异常处理**:考虑到可能...
在C语言中,我们可以使用系统调用如`sem_init()`、`sem_wait()`和`sem_post()`来创建和操作信号量。信号量分为两种:互斥量(mutex semaphore)和计数信号量。在这个问题中,我们通常需要一个互斥量来保护缓冲区,...