我有多个线程正在运行,需要附加到同一个队列。这个队列被分成多个变量,所以有效地,我调用一个函数,它附加到某个位置i的每个变量。从http://www.youtube.com/watch?v=8sgDgXUUJ68&feature=c4-overview-vl&list=PLBB24CFB073F1048E我看到我为每个方法添加了锁,如下所示。 http://www.caveofprogramming.com/java/java-multiple-locks/。在数组中为100,000个对象创建锁定似乎没有效果。在java中,假设我有一个管理大型对象队列的对象。如何通过同步方法来正确地同步addToQueue,而不是牺牲性能,只是我追加的floatQueue和intQueue中的位置?
class QueueManager {
private float[] floatQueue;
private int[] intQueue;
private int currentQueueSize;
private int maxQueueSize;
QueueManager(int sizeOfQueue) {
intQueue = new int[sizeOfQueue];
floatQueue = new float[sizeOfQueue];
currentQueueSize = 0;
maxQueueSize = sizeOfQueue;
}
public boolean addToQueue(int a, float b) {
if (currentQueueSize == maxQueueSize) {
return false;
}
else{
intQueue[currentQueueSize] = a;
floatQueue[currentQueueSize] = b;
currentQueueSize++;
return true;
}
}
}
答案 0 :(得分:3)
考虑使用BlockingQueue(java.util.concurrent)http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
答案 1 :(得分:2)
java.util.concurrent.ConcurrentLinkedQueue
是一个非阻塞,无锁的队列实现。它使用比较和交换指令而不是锁定。
答案 2 :(得分:0)
最好使用Blocking Queue而不是重新发明轮子。如果您正在练习练习,那么您可以使用两个锁定,一个用于放置,另一个用于获取。请参阅阻止队列的来源。
只是侧面说明正确获得并发是棘手的,所以不要在部署应用程序中使用队列,而是依赖Java的实现。
答案 3 :(得分:0)
要保持并行阵列“同步”,您需要同步。这是保持对数组及其相关索引的修改的原子性的唯一方法。
您可以考虑使用final
和int
的{{1}}字段,而不是并行数组,然后将这些字段添加到float
实现中,例如BlockingQueue
。
如果有很多流失(频繁创建和丢弃对象),ArrayBlockingQueue
可能会比元组表现更好。你需要对它们进行分析才能确定。
答案 4 :(得分:0)
我发现的一个可能的解决方案是使用AtomicIntegers,它类似于锁定,但运行的程度远低于synchronized。这是我的代码的更新副本,使用了AtomicInteger。请注意,它仍然需要进行测试,但从理论上讲,它应该足够了。
import java.util.concurrent.atomic.AtomicInteger;
class ThreadSafeQueueManager {
private float[] floatQueue;
private int[] intQueue;
private AtomicInteger currentQueueSize;
private int maxQueueSize;
QueueManager(int sizeOfQueue) {
intQueue = new int[sizeOfQueue];
floatQueue = new float[sizeOfQueue];
currentQueueSize = new AtomicInteger(0);
maxQueueSize = sizeOfQueue;
}
public boolean addToQueue(int a, float b) {
if (currentQueueSize.get() == maxQueueSize) {
return false;
}
else{
try {
// Subtract one so that the 0th position can be used
int position = currentQueueSize.incrementAndGet() - 1;
intQueue[position] = a;
floatQueue[positions] = b;
return true;
}
catch (ArrayIndexOutOfBoundsException e) { return false;}
}
}
}
另外,作为参考,值得一读
https://www.ibm.com/developerworks/java/library/j-jtp11234/
http://www.ibm.com/developerworks/library/j-jtp04186/