Java 使用线程的生产者-消费者
我正在编写一个程序,使用多线程概念在Java中实现生产者-消费者问题。下面是我应该如何做的几个细节: 1) 主线程应该创建一个缓冲区,其容量指定为命令行参数。生产者线程和消费者线程的数量也指定为命令行参数。我应该为每个生产者和消费者线程分配一个唯一的编号。如何为生产者和消费者线程分配唯一编号 2) 生产者线程在无限循环中运行。它生成具有以下格式的数据项(一个字符串):Java 使用线程的生产者-消费者,java,multithreading,consumer,producer,Java,Multithreading,Consumer,Producer,我正在编写一个程序,使用多线程概念在Java中实现生产者-消费者问题。下面是我应该如何做的几个细节: 1) 主线程应该创建一个缓冲区,其容量指定为命令行参数。生产者线程和消费者线程的数量也指定为命令行参数。我应该为每个生产者和消费者线程分配一个唯一的编号。如何为生产者和消费者线程分配唯一编号 2) 生产者线程在无限循环中运行。它生成具有以下格式的数据项(一个字符串):\u。例如,线程编号1的第一个数据项将为1_1,线程编号3的第二个数据项将为3_2。如何以这种格式创建数据项 3) 然后生产者线程
\u
。例如,线程编号1的第一个数据项将为1_1,线程编号3的第二个数据项将为3_2。如何以这种格式创建数据项
3) 然后生产者线程将一个条目写入生产者日志文件(
)。在写入日志条目时,它会尝试插入缓冲区。如果插入成功,它将在日志文件中创建一个条目(
“插入成功”)。如何编写这样的代码
下面是我编写的Java代码
import java.util.*;
import java.util.logging.*;
public class PC2
{
public static void main(String args[])
{
ArrayList<Integer> queue = new ArrayList<Integer>();
int size = Integer.parseInt(args[2]);
Thread[] prod = new Thread[Integer.parseInt(args[0])];
Thread[] cons = new Thread[Integer.parseInt(args[1])];
for(int i=0; i<prod.length; i++)
{
prod[i] = new Thread(new Producer(queue, size));
prod[i].start();
}
for(int i=0; i<cons.length; i++)
{
cons[i] = new Thread(new Consumer(queue, size));
cons[i].start();
}
}
}
class Producer extends Thread
{
private final ArrayList<Integer> queue;
private final int size;
public Producer(ArrayList<Integer> queue, int size)
{
this.queue = queue;
this.size = size;
}
public void run()
{
while(true){
for(int i=0; i<size; i++)
{
System.out.println("Produced: "+i+" by id " +Thread.currentThread().getId());
try
{
produce(i);
Thread.sleep(3000);
}
catch(Exception e)
{
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, e);
}
}}
}
public void produce(int i) throws InterruptedException
{
while(queue.size() == size)
{
synchronized(queue)
{
System.out.println("Queue is full "+Thread.currentThread().getName() +" is waiting, size: "+queue.size());
queue.wait();
}
}
synchronized(queue)
{
queue.add(i);
queue.notifyAll();
}
}
}
class Consumer extends Thread
{
private final ArrayList<Integer> queue;
private final int size;
public Consumer(ArrayList<Integer> queue, int size)
{
this.queue = queue;
this.size = size;
}
public void run()
{
while(true)
{
try
{ System.out.println("Consumed: "+consume());
Thread.sleep(1000);
}
catch(Exception e)
{
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, e);
}
}
}
public int consume() throws InterruptedException
{
while(queue.isEmpty())
{
synchronized(queue)
{
System.out.println("Queue is empty "+Thread.currentThread().getName()+" is waiting, size: "+queue.size());
queue.wait();
}
}
synchronized (queue)
{
queue.notifyAll();
System.out.println("Consumed by id "+Thread.currentThread().getId());
return (Integer) queue.remove(0);
}
}
}
import java.util.*;
导入java.util.logging.*;
公共类PC2
{
公共静态void main(字符串参数[])
{
ArrayList队列=新建ArrayList();
int size=Integer.parseInt(args[2]);
线程[]prod=新线程[Integer.parseInt(args[0]);
Thread[]cons=新线程[Integer.parseInt(args[1])];
对于(int i=0;i
我应该给每个生产者和消费者分配一个唯一的编号
线程。如何为生产者和消费者分配唯一编号
线程
将实例(非静态)变量添加到Producer/Consumer类。初始化新的Producer/Consumer对象时,请传入唯一的编号。您可以使用主类中的int计数器
跟踪所使用的编号
2) 生产者线程在无限循环中运行
具有以下格式的数据项(字符串):_<
数据项编号>。例如,线程编号中的第一个数据项
1将是1_1,螺纹编号3的第二个数据项将是3_2。
如何以这种格式创建数据项
使用同步方法和/或原子变量
3) 然后,生产者线程将一个条目写入生产者日志文件
(“已生成”)。在写入日志时
条目,它尝试插入缓冲区。如果
成功后,它将在日志文件中创建一个条目(
“插入成功”)。如何编写这样的代码
我的答案与上一个问题相同:阅读Java并发。花一个小时阅读同步、锁和原子变量,我保证您会轻松编写程序。对于生产者-消费者问题,最好的解决方案是阻塞队列。我正在测试一些东西,这样设计的同类程序现在修改了它根据你的需要
看看是否有帮助
import java.util.concurrent.*;
public class ThreadingExample {
public static void main(String args[]){
BlockingQueue<Message> blockingQueue = new ArrayBlockingQueue<Message>(100);
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Producer(blockingQueue));
exec.execute(new Consumer(blockingQueue));
}
}
class Message{
private static int count=0;
int messageId;
Message(){
this.messageId=count++;
System.out.print("message Id"+messageId+" Created ");
}
}
class Producer implements Runnable{
private BlockingQueue<Message> blockingQueue;
Producer(BlockingQueue<Message> blockingQueue){
this.blockingQueue=blockingQueue;
}
@Override
public void run(){
while(!Thread.interrupted()){
System.out.print("Producer Started");
try {
blockingQueue.put(new Message());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer Done");
}
}
}
class Consumer implements Runnable{
private BlockingQueue<Message> blockingQueue;
Consumer(BlockingQueue<Message> blockingQueue){
this.blockingQueue=blockingQueue;
}
@Override
public void run(){
while(!Thread.interrupted()){
System.out.print("Concumer Started");
try{
Message message = blockingQueue.take();
System.out.print("message Id"+message.messageId+" Consumed ");
}
catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Concumer Done");
}
}
}
import java.util.concurrent.*;
公共类线程示例{
公共静态void main(字符串参数[]){
BlockingQueue BlockingQueue=新阵列BlockingQueue(100);
ExecutorService exec=Executors.newCachedThreadPool();
exec.execute(新生产者(阻塞队列));
exec.execute(新消费者(阻塞队列));
}
}
类消息{
私有静态整数计数=0;
int-messageId;
消息(){
this.messageId=count++;
系统输出打印(“消息Id”+消息Id+“已创建”);
}
}
类生成器实现了Runnable{
私有阻塞队列阻塞队列;
生产者(封锁队列封锁队列){
this.blockingQueue=blockingQueue;
}
@凌驾
公开募捐{
而(!Thread.interrupted()){
系统输出打印(“生产商启动”);
试一试{
blockingQueue.put(新消息());
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(“生产商完成”);
}
}
}
类使用者实现Runnable{
私有阻塞队列阻塞队列;
消费者(封锁队列封锁队列){
this.blockingQueue=blockingQueue;
}
@凌驾
公开募捐{
而(!Thread.interrupted()){
系统输出打印(“启动震荡”);
试一试{
Message=blockingQueue.take();
系统输出打印(“消息Id”+消息.messageId+“已消费”);
}
捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(“震荡完成”);
}
}
}
我尝试了以下可能对您有用的方法,但3上的缓冲区条件除外,您可以自己添加部分代码。
希望这有帮助
public class Message {
private String msg;
public Message(String msg) {
super();
this.msg = msg;
}
public String getMsg(){
return msg;
}
}
import java.util.concurrent.BlockingQueue;
public class Producer implements Runnable {
private BlockingQueue<Message> queue;
private boolean run = true;
public Producer(BlockingQueue<Message> queue) {
super();
this.queue = queue;
}
public void setRun(boolean val) {
this.run = val;
}
@Override
public void run() {
int i = 0;
while (run) {
Message msg = new Message(Thread.currentThread().getName() + "_"+ i);
try {
Thread.sleep(i * 100);
queue.put(msg);
System.out.println("Producer: "+Thread.currentThread().getName()+" produced and added to the queue: "+msg.getMsg());
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
if(i==10){
setRun(false);
System.out.println(Thread.currentThread().getName()+" stopped");
}
}
}
}
import java.util.concurrent.BlockingQueue;
public class Consumer implements Runnable{
private BlockingQueue<Message> queue;
private boolean run = true;
public Consumer(BlockingQueue<Message> queue) {
super();
this.queue = queue;
}
public void setRun(boolean val){
this.run = val;
}
@Override
public void run() {
while(run){
try {
Thread.sleep(100);
Message msg = queue.take();
System.out.println("Consumer: "+Thread.currentThread().getName()+" generated/consumed "+msg.getMsg());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumerMain {
public static void main(String[] args) {
System.out
.println("please enter the number of producer:consumer:size of the queue in order");
Scanner scan = new Scanner(System.in);
Thread[] prodThreads = new Thread[scan.nextInt()];
Thread[] consThreads = new Thread[scan.nextInt()];
BlockingQueue<Message> queue = new ArrayBlockingQueue<Message>(scan.nextInt());
for (int i = 0; i < prodThreads.length; i++) {
prodThreads[i] = new Thread(new Producer(queue), "" + i);
prodThreads[i].start();
}
for (int i = 0; i < consThreads.length; i++) {
consThreads[i] = new Thread(new Consumer(queue), "" + i);
consThreads[i].start();
}
}
}
公共类消息{
私有字符串msg;
公共消息(字符串消息){
超级();
this.msg=msg;
}
公共字符串getMsg(){
返回味精;
}
}
导入java.util.concurrent.BlockingQueue;
公共类生产者实现Runnable{
私有阻塞队列;
私有布尔运行=true;
公共生产者(封锁队列){
超级();
this.queue=队列;
}
公共void setRun(布尔值){
this.run=val;
}
@凌驾
公开募捐{
int i=0;
while(运行){
Message msg=新消息(Thread.currentThread().getName()+“_”+i);
试一试{
睡眠(i*100);
queue.put(msg);
System.out.println(“Producer:+Thread.currentThread().getName()+”已生成并添加到队列:+msg.getMsg());
}捕捉(中断异常e){
e、 printStackTra
import java.util.LinkedList;
import java.util.Queue;
public class ProducerConsumerProblem {
public static int CAPACITY = 10; // At a time maximum of 10 tasks can be
// produced.
public static int PRODUCERS = 2;
public static int CONSUMERS = 4;
public static void main(String args[]) {
Queue<String> mTasks = new LinkedList<String>();
for (int i = 1; i <= PRODUCERS; i++) {
Thread producer = new Thread(new Producer(mTasks));
producer.setName("Producer " + i);
producer.start();
}
for (int i = 1; i <= CONSUMERS; i++) {
Thread consumer = new Thread(new Consumer(mTasks));
consumer.setName("Consumer " + i);
consumer.start();
}
}
}
class Producer implements Runnable {
Queue<String> mSharedTasks;
int taskCount = 1;
public Producer(Queue<String> mSharedTasks) {
super();
this.mSharedTasks = mSharedTasks;
}
@Override
public void run() {
while (true) {
synchronized (mSharedTasks) {
try {
if (mSharedTasks.size() == ProducerConsumerProblem.CAPACITY) {
System.out.println("Producer Waiting!!");
mSharedTasks.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while (mSharedTasks.size() != ProducerConsumerProblem.CAPACITY) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
String produceHere = Thread.currentThread().getName()
+ "_Item number_" + taskCount++;
synchronized (mSharedTasks) {
mSharedTasks.add(produceHere);
System.out.println(produceHere);
if (mSharedTasks.size() == 1) {
mSharedTasks.notifyAll(); // Informs consumer that there
// is something to consume.
}
}
}
}
}
}
class Consumer implements Runnable {
Queue<String> mSharedTasks;
public Consumer(Queue<String> mSharedTasks) {
super();
this.mSharedTasks = mSharedTasks;
}
@Override
public void run() {
while (true) {
synchronized (mSharedTasks) {
if (mSharedTasks.isEmpty()) { // Checks whether there is no task
// to consume.
try {
mSharedTasks.wait(); // Waits for producer to produce!
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
while (!mSharedTasks.isEmpty()) { // Consumes till task list is
// empty
try {
// Consumer consumes late hence producer has to wait...!
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (mSharedTasks) {
System.out.println(Thread.currentThread().getName()
+ " consumed " + mSharedTasks.poll());
if (mSharedTasks.size() == ProducerConsumerProblem.CAPACITY - 1)
mSharedTasks.notifyAll();
}
}
}
}
}
public class ProducerConsumerTest {
public static void main(String[] args) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
p1.start();
c1.start();
}
}
class CubbyHole {
private int contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) {
}
}
contents = value;
available = true;
notifyAll();
}
}
class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("Consumer #"
+ this.number
+ " got: " + value);
}
}
}
class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("Producer #" + this.number
+ " put: " + i);
try {
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}