我需要编写一个类似于生产者-
消费者的问题,必须使用信号量。我尝试了几种解决方案,但都无济于事。首先,我在Wikipedia上尝试了一个解决方案,但没有成功。我当前的代码是这样的:
使用者的方法运行:
public void run() {
int i=0;
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String s = new String();
while (1!=2){
Date datainicio = new Date();
String inicio=dateFormat.format(datainicio);
try {
Thread.sleep(1000);///10000
} catch (InterruptedException e) {
System.out.println("Excecao InterruptedException lancada.");
}
//this.encheBuffer.down();
this.mutex.down();
// RC
i=0;
while (i<buffer.length) {
if (buffer[i] == null) {
i++;
} else {
break;
}
}
if (i<buffer.length) {
QuantidadeBuffer.quantidade--;
Date datafim = new Date();
String fim=dateFormat.format(datafim);
int identificador;
identificador=buffer[i].getIdentificador()[0];
s="Consumidor Thread: "+Thread.currentThread()+" Pedido: "+identificador+" Inicio: "+inicio+" Fim: "+fim+" posicao "+i;
//System.out.println("Consumidor Thread: "+Thread.currentThread()+" Pedido: "+identificador+" Inicio: "+inicio+" Fim: "+fim+" posicao "+i);
buffer[i]= null;
}
// RC
this.mutex.up();
//this.esvaziaBuffer.up();
System.out.println(s);
// lock.up();
}
}
生产者的方法运行:
public void run() {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
int i=0;
while (1!=2){
Date datainicio = new Date();
String inicio=dateFormat.format(datainicio);
// Produz Item
try {
Thread.sleep(500);//50000
} catch (InterruptedException e) {
System.out.println("Excecao InterruptedException lancada.");
}
//this.esvaziaBuffer.down();
this.mutex.down();
// RC
i=0;
while (i<buffer.length) {
if (buffer[i]!=null) {
i++;
} else {
break;
}
}
if (i<buffer.length) {
int identificador[]=new int[Pedido.getTamanho_identificador()];
identificador[0]=i;
buffer[i]=new Pedido();
Produtor.buffer[i].setIdentificador(identificador);
Produtor.buffer[i].setTexto("pacote de dados");
QuantidadeBuffer.quantidade++;
Date datafim = new Date();
String fim=dateFormat.format(datafim);
System.out.println("Produtor Thread: "+Thread.currentThread()+" Pedido: "+identificador[0]+" Inicio: "+inicio+" Fim: "+fim+" posicao "+i);
i++;
}
// RC
this.mutex.up();
//this.encheBuffer.up();
}
//this.encheBuffer.up();
}
在上面的代码中,发生了一个消费者线程读取一个位置,然后另一个线程读取了相同位置而没有生产者填充该位置的情况,如下所示:
Consumidor Thread: Thread[Thread-17,5,main] Pedido: 1 Inicio: 2011/11/27 17:23:33 Fim: 2011/11/27 17:23:34 posicao 1
Consumidor Thread: Thread[Thread-19,5,main] Pedido: 1 Inicio: 2011/11/27 17:23:33 Fim: 2011/11/27 17:23:34 posicao 1
似乎您使用的是互斥锁而不是信号灯?
使用互斥锁时,您只有二进制同步-锁定和解锁一个资源。Sempahores具有您可以传达或获取的价值。
您试图锁定/解锁整个缓冲区,但这是错误的方法,因为正如您所看到的,生产者或使用者锁定,并且当读者锁定它时,生产者无法填充该缓冲区(因为它必须先锁定)。
相反,您应该创建一个Sempahore,然后,当生产者写入一个数据包或数据块时,它可以发出信号量信号。然后,消费者可以尝试获取信号量,因此他们将等到生产者发出已写入数据包的信号。在发信号通知已写数据包后,将唤醒一个使用方,并且它将知道它可以读取一个数据包。它可以读取数据包,然后返回尝试获取信号量。如果在那个时候生产者已经写了另一个数据包,它又发出了信号,那么任何一个消费者都将继续读取另一个数据包。等等…
例如:
(生产者)-写一个数据包-Semaphore.release(1)
(消费者xN)-Semaphore.acquire(1)-读取一个数据包
如果你有多个消费者,则 消费者 (而非生产者)应当读操作时的数据包(但锁定缓冲区 不
获取信号时),以防止竞争条件。在下面的示例中,由于所有内容都在同一JVM上,因此生产者还锁定了列表。
import java.util.LinkedList;
import java.util.concurrent.Semaphore;
public class Semaphores {
static Object LOCK = new Object();
static LinkedList list = new LinkedList();
static Semaphore sem = new Semaphore(0);
static Semaphore mutex = new Semaphore(1);
static class Consumer extends Thread {
String name;
public Consumer(String name) {
this.name = name;
}
public void run() {
try {
while (true) {
sem.acquire(1);
mutex.acquire();
System.out.println("Consumer \""+name+"\" read: "+list.removeFirst());
mutex.release();
}
} catch (Exception x) {
x.printStackTrace();
}
}
}
static class Producer extends Thread {
public void run() {
try {
int N = 0;
while (true) {
mutex.acquire();
list.add(new Integer(N++));
mutex.release();
sem.release(1);
Thread.sleep(500);
}
} catch (Exception x) {
x.printStackTrace();
}
}
}
public static void main(String [] args) {
new Producer().start();
new Consumer("Alice").start();
new Consumer("Bob").start();
}
}
本文向大家介绍使用信号量的生产者消费者问题,包括了使用信号量的生产者消费者问题的使用技巧和注意事项,需要的朋友参考一下 生产者消费者问题是同步问题。有一个固定大小的缓冲区,生产者生产商品并将其输入缓冲区。消费者从缓冲区中删除项目并消费它们。 当消费者从缓冲区中消费商品时,生产者不应将商品生产到缓冲区中,反之亦然。因此,缓冲区只能一次由生产者或使用者访问。 生产者消费者问题可以使用信号量解决。生产者
我应该在两个子进程中获得信号量ID…还是缺少其他东西。
我正在编写一个程序,其中几个生产者生成一些应该由几个消费者处理的数据。由于每条数据的消耗大约需要100ms,而目标平台有很多处理器,所以在我看来,每个生产者和每个消费者都得到自己的线程似乎是很自然的。我的问题是:Qt信号/插槽是将数据块从生产者传递到消费者的好方法吗?还是建议更好的解决方案(强烈首选Qt)。 为了防患于未然,制作者每小时产生几十万个数据。
我有一个消费者作为生产者消费者模式的一部分: 简化: 如果我移除 通过将线程设置为睡眠,CPU使用率攀升到极高的水平(13%),而不是0%。 此外,如果我实例化该类的多个实例,则每个实例的CPU使用率都会以13%的增量攀升。 大约每分钟(可能每30秒)都会向BlockingCollection添加一个新的LogItem,并将适用的消息写入文件。 有没有可能线程以某种方式阻止了其他线程的运行,而系统
本文向大家介绍Java如何通过线程解决生产者/消费者问题,包括了Java如何通过线程解决生产者/消费者问题的使用技巧和注意事项,需要的朋友参考一下 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示 生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生
本教程演示了如何发送和接收来自Spring Kafka的消息。 首先创建一个能够发送消息给Kafka主题的Spring Kafka Producer。 接下来,我们创建一个Spring Kafka Consumer,它可以收听发送给Kafka主题的消息。使用适当的键/值序列化器和解串器来配置它们。 最后用一个简单的Spring Boot应用程序演示应用程序。 下载并安装Apache Kafka 要