java中的多个线程附加到队列

时间:2013-08-30 22:13:30

标签: java multithreading locks

我有多个线程正在运行,需要附加到同一个队列。这个队列被分成多个变量,所以有效地,我调用一个函数,它附加到某个位置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;
        }
    }
}

5 个答案:

答案 0 :(得分:3)

答案 1 :(得分:2)

java.util.concurrent.ConcurrentLinkedQueue是一个非阻塞,无锁的队列实现。它使用比较和交换指令而不是锁定。

答案 2 :(得分:0)

最好使用Blocking Queue而不是重新发明轮子。如果您正在练习练习,那么您可以使用两个锁定,一个用于放置,另一个用于获取。请参阅阻止队列的来源。

只是侧面说明正确获得并发是棘手的,所以不要在部署应用程序中使用队列,而是依赖Java的实现。

答案 3 :(得分:0)

要保持并行阵列“同步”,您需要同步。这是保持对数组及其相关索引的修改的原子性的唯一方法。

您可以考虑使用finalint的{​​{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/