这是场景:
我有3条车道想要从中移动箱子。每个框都有一个groupId。这样车道将被分配到一个组。
因此,当我收到具有唯一groupId的第一个移动请求时,我将创建一个列表并将此请求添加到该列表中,然后开始处理该列表。如果我收到另一个具有相同groupId的请求,则必须添加到同一列表中
(此列表用于处理不同线程中的请求),
否则创建一个新列表并分配一个新车道并开始处理。
请提出一个Java集合,以帮助有效地实现此目标。
任何帮助将不胜感激!
答案 0 :(得分:0)
如果需要对int lostSheep(const int *friday, size_t sz1,
const int* saturday, size_t sz2,
int total)
{
size_t i;
for (i = 0; i < sz1; ++i) {
total -= friday[i];
}
for (i = 0; i < sz2; ++i) {
total -= saturday[i];
}
return total;
}
进行突变并从多个线程中进行读取,那么您可能正在寻找List<T>
。无论如何,如果用例足够复杂,我会实施 my 锁定策略。
当我收到具有唯一groupId的第一招请求时,我将创建一个 列表,然后将此请求添加到该列表中,然后开始处理 列表,如果我收到另一个具有相同groupId的请求,则必须添加到同一列表中
我认为您最好使用带有CopyOnWriteArrayList
块的自定义锁定策略。
答案 1 :(得分:0)
我怀疑List
是否适合您的用例。由于您是在线程之间传递数据,因此BlockingQueue
似乎更加自然。
作为示例,以下是基于以下假设的实现:
有1个box
生产者,即:
1)生成box
,其中groupId
的随机范围为1到3
2)将box
放入单 lane
有3个box
消费者,每个消费者:
1)从box
收到lane
2)如果消费者的groupId
与盒子groupId
匹配,则消耗该盒子
不使用其他框架(仅核心Java)
import java.util.*;
import java.util.concurrent.*;
class Answer {
public static void main(String[] args) {
LinkedBlockingQueue<Box> lane = new LinkedBlockingQueue<>();
Producer p = new Producer(lane);
Consumer c1 = new Consumer(1, lane);
Consumer c2 = new Consumer(2, lane);
Consumer c3 = new Consumer(3, lane);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
new Thread(c3).start();
}
}
class Producer implements Runnable {
private final LinkedBlockingQueue<Box> lane;
Producer(LinkedBlockingQueue<Box> lane) {
this.lane = lane;
}
public void run() {
try {
while (true) {
lane.put(new Box(produceGroupId()));
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt(); // set interrupt flag
}
}
int produceGroupId() {
// generate random int between 1 and 3
return ThreadLocalRandom.current().nextInt(1, 4);
}
}
class Consumer implements Runnable {
private final int groupId;
private final BlockingQueue<Box> lane;
Consumer(int groupId, BlockingQueue<Box> lane) {
this.groupId = groupId;
this.lane = lane;
}
public void run() {
while (true) {
Box box = lane.peek();
if (box != null && box.getGroupId() == this.groupId) {
consume(lane.poll());
}
}
}
void consume(Box box) {
System.out.println("Consumer " + groupId + " received " + box + " for proxessing.");
}
}
class Box {
private final int groupId;
public Box(int groupId) {
this.groupId = groupId;
}
public int getGroupId() {
return this.groupId;
}
@Override
public String toString() {
return "<Box " + groupId + ">";
}
}
如果目标是拥有 3条单独的车道,则实施会有所不同:
import java.util.*;
import java.util.concurrent.*;
class Answer {
public static void main(String[] args) {
BlockingQueue<Box> lane1 = new LinkedBlockingQueue<Box>();
BlockingQueue<Box> lane2 = new LinkedBlockingQueue<Box>();
BlockingQueue<Box> lane3 = new LinkedBlockingQueue<Box>();
Map<Integer, BlockingQueue<Box>> lanes = new ConcurrentHashMap<Integer, BlockingQueue<Box>>();
lanes.put(1, lane1);
lanes.put(2, lane2);
lanes.put(3, lane3);
Producer p = new Producer(lanes);
Consumer c1 = new Consumer(1, lane1);
Consumer c2 = new Consumer(2, lane2);
Consumer c3 = new Consumer(3, lane3);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
new Thread(c3).start();
}
}
class Producer implements Runnable {
private final Map<Integer, BlockingQueue<Box>> lanes;
Producer(Map<Integer, BlockingQueue<Box>> lanes) {
this.lanes = lanes;
}
public void run() {
try {
while (true) {
int groupId = produceGroupId();
BlockingQueue<Box> lane = lanes.get(groupId);
lane.put(new Box(groupId));
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
int produceGroupId() {
// generate random int between 1 and 3
return ThreadLocalRandom.current().nextInt(1, 4);
}
}
class Consumer implements Runnable {
private final int consumerId;
private final BlockingQueue<Box> lane;
Consumer(int consumerId, BlockingQueue<Box> lane) {
this.consumerId = consumerId;
this.lane = lane;
}
public void run() {
try {
while (true) {
consume(lane.take());
}
} catch (InterruptedException ex) {}
}
void consume(Box box) {
System.out.println("Consumer " + consumerId + " received " + box + " for proxessing.");
}
}
class Box {
private final int groupId;
public Box(int groupId) {
this.groupId = groupId;
}
public int getGroupId() {
return this.groupId;
}
@Override
public String toString() {
return "<Box " + groupId + ">";
}
}