如何测试阻塞队列实现的同步

时间:2016-04-01 16:02:08

标签: java synchronization thread-safety

我刚刚用信号量编写了一个简单的阻塞队列,我将测试它的同步。

我已经在大量插入和从队列中删除的线程上测试了我的实现稳定性,

我想获得一些关于如何以更正确的方式测试它的想法\测试的帮助。

public class BBQ<T> {
private ArrayList<T> tasks;
private Semaphore mutex;
private Semaphore full;
private Semaphore zero;

public BBQ(int numofWorkers){
    tasks = new ArrayList<T>();
    mutex = new Semaphore(1, true);
    full = new Semaphore(numofWorkers, true);
    zero = new Semaphore(0, true);
}

public boolean add(T item) {
    boolean ans = false;

    try {
        zero.acquire();
        mutex.acquire();
        ans = tasks.add(item);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    finally{
        mutex.release();
        full.release();

    }
    return ans;
}

public boolean remove() {
    boolean ans = false;
    try {
        full.acquire();
        mutex.acquire();
        if (tasks.remove(0) == null) {
            ans = false;
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    finally{
        mutex.release();
        zero.release();
    }
    return ans;
}

public int size() {
    return tasks.size();
}

public String toString() {
    return tasks.toString();
}

3 个答案:

答案 0 :(得分:0)

您的sizetoString不是线程安全的。没有万无一失的测试线程安全性的方法,你编写的代码要好得多,以便理解和验证。

据说,进行简单测试并不会有什么坏处,因为这可能会显示错误。 (没有错误并不意味着它是线程安全的)

我会使用ExecutorService尽快添加和删除条目,看看它是否进入错误状态。特别是每次都会调用toString(),因为我很确定这会失败,这是你应该能够展示的。

答案 1 :(得分:0)

我会运行3种类型的测试来测试你的阻止代码:

  1. 死锁测试 - 使用随机时间间隔延迟运行调用线程。死锁难以重现,随机延迟更容易消除问题。从您的代码中可以看出,由于锁定序列相同,因此不会发生死锁。
  2. 性能 - 您提到了大量的线程。使用阻塞代码会导致后续线程的执行延迟
  3. 多CPU测试 - 您可能希望在多个vCPU VM上对其进行测试,以查看它是否可以扩展到多个CPU。我认为可能因为你使用的是共享内存

答案 2 :(得分:0)

  

我希望得到一些关于如何以更正确的方式测试它的想法\测试方面的帮助。

您可以使用jcstress框架。某些Oracle工程师使用它进行内部测试