Java 中的并发编程。试图模拟一组结账柜台
Concurrent Programming in Java. Trying to simulate a set of checkout counters
我正在尝试使用 Java 模拟购物中心的一组结账柜台。
这是假设。有5个结账柜台。就像一个真正的购物中心,每个柜台都有一条线。每个柜台一次服务一位顾客。
我尝试按如下方式实现:
每个客户都是一个class运行一个类似于生产者-消费者问题中生产者的线程。客户是阻塞队列的一部分。我将以某种方式需要一组阻塞队列来模拟 5 个结账柜台前的 5 条线。我该如何实现。
结账柜台已定义为单线程执行器服务。所以现在将有 5 个执行程序一次为一个(生产者)线程提供服务。我已经定义了一个执行器数组列表来模拟这组 5.
在柜台,执行者服务正在执行其相应队列中的一个线程(即消费者正在消费生产者生产的东西)。
我的逻辑正确吗?
我有一些代码,但我不确定这段代码是否正确执行了我的逻辑。
请帮忙。
干杯..
代码:
Checkout.java
package Supermarket;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Checkout implements Runnable
{
public BlockingQueue<Integer> item_queue = new ArrayBlockingQueue<Integer>(10);
public int checkout_number;
public int item;
public Random random;
public Checkout(int checkout_number, BlockingQueue<Integer> item_queue)
{
this.checkout_number = checkout_number;
this.item_queue = item_queue;
random = new Random();
System.out.println("\nCheckout Counter Number: "+checkout_number);
}
public void run()
{
while(true)
{
if(item == -1)
{
System.out.println("Consumer finished");
break;
}
else
{
try
{
item = item_queue.take();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("\nConsumer has taken item ==> "+item);
System.out.println("Scanning item");
try
{
Thread.sleep(random.nextInt(5000));
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Customer.java
package Supermarket;
import java.util.*;
import java.util.concurrent.*;
public class Customer implements Runnable
{
public int item;
public int customer_number;
public int i;
public int item_count;
public Random random = new Random();
public BlockingQueue<Integer> item_queue = new ArrayBlockingQueue<Integer>(10);
public Customer(int customer_number, BlockingQueue<Integer> item_queue)
{
this.customer_number = customer_number;
this.item_queue = item_queue;
}
public void run()
{
item_count = random.nextInt(5);
System.out.println("I am customer Number: "+customer_number+" and I have "+item_count+" items");
for(i=0; i<item_count; i++)
{
try
{
item_queue.put(random.nextInt(10));
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
item_queue.put(-1);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Driver.java
package Supermarket;
import java.util.concurrent.*;
import java.util.*;
public class Driver
{
public static BlockingQueue<Integer> item_queue = new ArrayBlockingQueue<Integer>(10);
public static Random random = new Random();
public static int customer_count;
public static int checkout_count;
public static int i;
public static void main(String[] args) {
// TODO Auto-generated method stub
customer_count = random.nextInt(4)+1;
// checkout_count = 5;
System.out.println("Total Number of Customers: "+customer_count+"\n");
for(i=0; i<customer_count; i++)
{
Customer customer = new Customer(i+1, item_queue);
Thread customer_thread = new Thread(customer);
customer_thread.start();
}
// for(i=0; i<=checkout_count; i++)
// {
// Checkout checkout = new Checkout(1, item_queue);
// Thread checkout_thread = new Thread(checkout);
// checkout_thread.start();
// }
// System.out.println("\n\nProgram Terminates!\n\n");
}
}
我的逻辑是这样的:
- 将结账柜台写成自己的线程
- 将线路(客户线路)写成普通列表。它不一定是
BlockingDeque
,因为每个结账柜台处理它自己的行。
这样它就会像真正的超市一样运作,每个结账柜台处理自己的线路。
基于此我觉得写代码应该更符合逻辑。
您的模拟可能需要考虑更多功能。例如,您可能需要考虑以下部分或全部设计注意事项:
客户
每个客户都有以下特点
- 一组要购买的物品。
- 所有商品均一次性购买,而非一次购买一件
- 单笔交易中可能有 0..* 件商品。
- 一笔 0 件商品的交易产生了 0.00 美元的收据。
- 客户识别
- 到达收银台的时间
- 完成结帐交易的时间
- 购买交易的价值(即收据)
收银台
每个收银台都有以下特点
排队等候结账的顾客。
队列中可能有 0..* 位顾客在等待结账
队列中的客户数量对每个客户都可用
入队前
客户总是选择可用的最短结账队列
进入结帐队列后,所有客户都留在该队列中,直到他们
事务已处理。
结账柜台 ID
自商店开业以来服务的客户统计
- 0 项交易不会增加所服务客户的总数
收银台处理的所有销售总额
商店库存
可购买的物品集是商店库存。
每一项都有以下特点
项目编号
物品成本
客户购买的一组商品仅包含每个商品的商品 ID。特定商品 ID 可能会在客户选择购买的商品列表中出现多次。
我正在尝试使用 Java 模拟购物中心的一组结账柜台。
这是假设。有5个结账柜台。就像一个真正的购物中心,每个柜台都有一条线。每个柜台一次服务一位顾客。
我尝试按如下方式实现:
每个客户都是一个class运行一个类似于生产者-消费者问题中生产者的线程。客户是阻塞队列的一部分。我将以某种方式需要一组阻塞队列来模拟 5 个结账柜台前的 5 条线。我该如何实现。
结账柜台已定义为单线程执行器服务。所以现在将有 5 个执行程序一次为一个(生产者)线程提供服务。我已经定义了一个执行器数组列表来模拟这组 5.
在柜台,执行者服务正在执行其相应队列中的一个线程(即消费者正在消费生产者生产的东西)。
我的逻辑正确吗?
我有一些代码,但我不确定这段代码是否正确执行了我的逻辑。
请帮忙。 干杯..
代码:
Checkout.java
package Supermarket;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Checkout implements Runnable
{
public BlockingQueue<Integer> item_queue = new ArrayBlockingQueue<Integer>(10);
public int checkout_number;
public int item;
public Random random;
public Checkout(int checkout_number, BlockingQueue<Integer> item_queue)
{
this.checkout_number = checkout_number;
this.item_queue = item_queue;
random = new Random();
System.out.println("\nCheckout Counter Number: "+checkout_number);
}
public void run()
{
while(true)
{
if(item == -1)
{
System.out.println("Consumer finished");
break;
}
else
{
try
{
item = item_queue.take();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("\nConsumer has taken item ==> "+item);
System.out.println("Scanning item");
try
{
Thread.sleep(random.nextInt(5000));
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Customer.java
package Supermarket;
import java.util.*;
import java.util.concurrent.*;
public class Customer implements Runnable
{
public int item;
public int customer_number;
public int i;
public int item_count;
public Random random = new Random();
public BlockingQueue<Integer> item_queue = new ArrayBlockingQueue<Integer>(10);
public Customer(int customer_number, BlockingQueue<Integer> item_queue)
{
this.customer_number = customer_number;
this.item_queue = item_queue;
}
public void run()
{
item_count = random.nextInt(5);
System.out.println("I am customer Number: "+customer_number+" and I have "+item_count+" items");
for(i=0; i<item_count; i++)
{
try
{
item_queue.put(random.nextInt(10));
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
item_queue.put(-1);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Driver.java
package Supermarket;
import java.util.concurrent.*;
import java.util.*;
public class Driver
{
public static BlockingQueue<Integer> item_queue = new ArrayBlockingQueue<Integer>(10);
public static Random random = new Random();
public static int customer_count;
public static int checkout_count;
public static int i;
public static void main(String[] args) {
// TODO Auto-generated method stub
customer_count = random.nextInt(4)+1;
// checkout_count = 5;
System.out.println("Total Number of Customers: "+customer_count+"\n");
for(i=0; i<customer_count; i++)
{
Customer customer = new Customer(i+1, item_queue);
Thread customer_thread = new Thread(customer);
customer_thread.start();
}
// for(i=0; i<=checkout_count; i++)
// {
// Checkout checkout = new Checkout(1, item_queue);
// Thread checkout_thread = new Thread(checkout);
// checkout_thread.start();
// }
// System.out.println("\n\nProgram Terminates!\n\n");
}
}
我的逻辑是这样的:
- 将结账柜台写成自己的线程
- 将线路(客户线路)写成普通列表。它不一定是
BlockingDeque
,因为每个结账柜台处理它自己的行。
这样它就会像真正的超市一样运作,每个结账柜台处理自己的线路。
基于此我觉得写代码应该更符合逻辑。
您的模拟可能需要考虑更多功能。例如,您可能需要考虑以下部分或全部设计注意事项:
客户
每个客户都有以下特点
- 一组要购买的物品。
- 所有商品均一次性购买,而非一次购买一件
- 单笔交易中可能有 0..* 件商品。
- 一笔 0 件商品的交易产生了 0.00 美元的收据。
- 客户识别
- 到达收银台的时间
- 完成结帐交易的时间
- 购买交易的价值(即收据)
收银台
每个收银台都有以下特点
排队等候结账的顾客。
队列中可能有 0..* 位顾客在等待结账
队列中的客户数量对每个客户都可用 入队前
客户总是选择可用的最短结账队列
进入结帐队列后,所有客户都留在该队列中,直到他们 事务已处理。
结账柜台 ID
自商店开业以来服务的客户统计
- 0 项交易不会增加所服务客户的总数
收银台处理的所有销售总额
商店库存
可购买的物品集是商店库存。 每一项都有以下特点
项目编号
物品成本
客户购买的一组商品仅包含每个商品的商品 ID。特定商品 ID 可能会在客户选择购买的商品列表中出现多次。