Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 共享物品生产者与消费者问题_Java_Multithreading_Concurrency_Synchronization_Producer Consumer - Fatal编程技术网

Java 共享物品生产者与消费者问题

Java 共享物品生产者与消费者问题,java,multithreading,concurrency,synchronization,producer-consumer,Java,Multithreading,Concurrency,Synchronization,Producer Consumer,我有一种生产者-消费者问题的味道(我找不到任何类似的问题,搜索关键词也用光了)在哪里 消费者本身就是生产者 生产的产品可以共享 如果某个线程正在生成,其他线程将等待它完成并使用相同的生成项 我想出了一个解决方案,但我一直在研究如何测试它。是否有一个理论框架来验证这类问题解决方案的正确性。也可以在不修改源代码的情况下测试这些解决方案吗 如果您对代码感兴趣,下面列出了它 import java.util.*; 导入java.util.concurrent.AtomicInteger; 公共类Shar

我有一种生产者-消费者问题的味道(我找不到任何类似的问题,搜索关键词也用光了)在哪里

  • 消费者本身就是生产者
  • 生产的产品可以共享
  • 如果某个线程正在生成,其他线程将等待它完成并使用相同的生成项
  • 我想出了一个解决方案,但我一直在研究如何测试它。是否有一个理论框架来验证这类问题解决方案的正确性。也可以在不修改源代码的情况下测试这些解决方案吗

    如果您对代码感兴趣,下面列出了它

    import java.util.*;
    导入java.util.concurrent.AtomicInteger;
    公共类SharedItemProducer{
    /*测试参数*/
    静态最终int randMax=1;
    静态最终随机R=新随机();
    静态final int numThreads=8;
    静态最终长生产延迟=0;
    静态最终长maxRunTime=5000;
    整数项=0;
    最终对象waitingRoom=新对象();
    AtomicInteger WantoBeProducer=新的AtomicInteger(0);
    公共产品{
    日志(“输入产品”);
    if(wantToBeProducer.compareAndSet(0,1)){
    日志(“我是制作人。cur=%d”,项);
    试一试{
    线程。睡眠(produceDelay);
    }捕捉(中断异常e){
    e、 printStackTrace();
    }
    项目=项目+1;
    已同步(等候室){
    waitingRoom.notifyAll();
    }
    wantToBeProducer.set(0);
    日志(“完成生产”);
    }否则{
    日志(“其他人正在制作、等待…”);
    已同步(等候室){
    试一试{
    等一下;
    }捕捉(中断异常e){
    e、 printStackTrace();
    }
    }
    日志(“等待完成”);
    }
    }
    公共静态void main(字符串[]args){
    长启动=System.currentTimeMillis();
    /*运行测试*/
    SharedItemProducer1 P=新的SharedItemProducer1();
    for(int i=0;i{
    while(true){
    P.生产();
    试一试{
    睡眠(R.nextInt(randMax));
    }捕捉(中断异常e){
    e、 printStackTrace();
    }
    }
    }).start();
    }
    /*限制测试时间*/
    新线程(()->{
    试一试{
    sleep(maxRunTime);
    }捕捉(中断异常e){
    e、 printStackTrace();
    }
    系统出口(0);
    }).start();
    }
    静态布尔启用日志=false;
    静态最终字符串FMT=“[%s][%s]”;
    公共静态无效日志(字符串信息、对象…参数){
    如果(!enableLog)
    返回;
    Object[]pfParams=新对象[params.length+2];
    系统阵列复制(参数,0,pfParams,2,参数长度);
    pfParams[0]=新日期();
    pfParams[1]=Thread.currentThread().getName();
    System.out.printf(FMT+info+“\n”,pfParams);
    }
    }
    
    如果我理解正确,您正在寻求一种控制线程交错的方法,以便验证可能的边缘情况和奇怪的场景

    我建议你看一下,看看是否有帮助

    它不仅讨论了测试并发代码的概念和策略,还提到了一些可能有用的工具,包括:

    请看一看,试一下

    为了更好地测试您的代码,我还建议您对其进行更多的模块化,以便您可以单独测试生产者和消费者


    编辑:若要生成测试用例,列出您可能希望在代码中验证的典型并发问题可能会有所帮助。请看一看这篇来自CMU SEI的博文,它要求提供一个广泛的列表

    谢谢你指出这篇文章。关于模块化,生产者和消费者是相同的线程。我建议仔细阅读,特别是解释为什么它应该在循环中执行(而测试条件必须包含在相同的
    synchronized
    块中)。当其他线程已经在
    wait()
    调用中,并且在
    synchronized
    块之外做出了进入等待状态的决定时,期望发生
    notify()
    调用是一厢情愿的想法。