Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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并发在实践中的应用&x201C;清单12.5。BoundedBuffer和#x201D的生产者-消费者测试计划;循环障碍有待理解?_Java_Multithreading_Concurrency - Fatal编程技术网

Java并发在实践中的应用&x201C;清单12.5。BoundedBuffer和#x201D的生产者-消费者测试计划;循环障碍有待理解?

Java并发在实践中的应用&x201C;清单12.5。BoundedBuffer和#x201D的生产者-消费者测试计划;循环障碍有待理解?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我在实践中阅读Java并发性,并遇到以下代码片段。 清单12.5 //清单12.5。BoundedBuffer的生产者-消费者测试程序。 包net.jcip.examples; 导入java.util.concurrent.*; 导入java.util.concurrent.atomic.*; 导入junit.framework.TestCase; /** *推杆试验 * *BoundedBuffer的生产者-消费者测试程序 * *@作者Brian Goetz和Tim Peierls */ 公共

我在实践中阅读Java并发性,并遇到以下代码片段。 清单12.5

//清单12.5。BoundedBuffer的生产者-消费者测试程序。
包net.jcip.examples;
导入java.util.concurrent.*;
导入java.util.concurrent.atomic.*;
导入junit.framework.TestCase;
/**
*推杆试验
*

*BoundedBuffer的生产者-消费者测试程序 * *@作者Brian Goetz和Tim Peierls */ 公共类PutTakeTest扩展了TestCase{ 受保护的静态最终执行器服务池=Executors.newCachedThreadPool(); 受保护的循环载体屏障; 受保护的最终信号量BoundedBuffer bb; 受保护的最终国际文件、NPAIR; 受保护的最终AtomicInteger putSum=新的AtomicInteger(0); 受保护的最终AtomicInteger takeSum=新的AtomicInteger(0); 公共静态void main(字符串[]args)引发异常{ new PutTakeTest(10,10,100000).test();//示例参数 pool.shutdown(); } 公共推杆测试(int容量、int NPAIR、int NTRIAL){ this.bb=新信号量BoundedBuffer(容量); this.nTrials=nTrials; this.nPairs=nPairs; 此.barrier=新循环载体(npairs*2+1); } 无效测试(){ 试一试{ 对于(int i=0;i>21); y^=(y 0;--i){ 把(种子); 总和+=种子; 种子=xorShift(种子); } putSum.getandad(sum); 障碍。等待(); }捕获(例外e){ 抛出新的运行时异常(e); } } } 类使用者实现Runnable{ 公开募捐{ 试一试{ 障碍。等待(); 整数和=0; 对于(int i=nTrials;i>0;--i){ sum+=bb.take(); } takeSum.getandad(sum); 障碍。等待(); }捕获(例外e){ 抛出新的运行时异常(e); } } } }

我发现很难理解如何在主线程或可运行线程中第二次调用循环屏障。根据我的理解,循环屏障将阻塞线程,直到在所有线程上调用wait并且屏障计数与构造函数中传递的值匹配为止。当线程上第一次等待屏障时,循环屏障中的等待计数将是所需值(npairs*2+1)的一半。控件如何在生产者和消费者中执行put sum和take sum计算,以及如何在主线程上连续执行


如果这个问题听起来很幼稚,请提前道歉。

在呼叫
等待
障碍之前,主线程启动
npairs
生产者和
npairs
消费者。每个if生产者和消费者调用
等待
,因此它与一个主线程一起允许所有线程通过屏障。

感谢您的澄清。我对Consumer类中的代码片段感到困惑。如果在run方法的第一行调用barrier await(),那么在同一方法中如何第二次调用barrier。使用者线程何时激活以在run方法中调用barrier wait第二次?public void run(){try{barrier.await();int sum=0;//计算和逻辑barrier.await();}catch(异常e){}当所有线程首先到达
等待
时,它们都会通过屏障并开始执行后续工作。然后他们到达第二个
等待
,当所有线程都在那里时,他们继续通过它并计算最终结果。当第一个等待在所有线程上调用并且线程开始计算总和时,循环屏障是否重置回线程数目的计数?是,我想Java Concyrency在实践中也提到了这一点,非常感谢!我不知怎的错过了周期性障碍物的重置。
// Listing 12.5. Producer-consumer test program for BoundedBuffer.
package net.jcip.examples;

import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

import junit.framework.TestCase;

/**
 * PutTakeTest
 * <p/>
 * Producer-consumer test program for BoundedBuffer
 *
 * @author Brian Goetz and Tim Peierls
 */
public class PutTakeTest extends TestCase {
    protected static final ExecutorService pool = Executors.newCachedThreadPool();
    protected CyclicBarrier barrier;
    protected final SemaphoreBoundedBuffer<Integer> bb;
    protected final int nTrials, nPairs;
    protected final AtomicInteger putSum = new AtomicInteger(0);
    protected final AtomicInteger takeSum = new AtomicInteger(0);

    public static void main(String[] args) throws Exception {
        new PutTakeTest(10, 10, 100000).test(); // sample parameters
        pool.shutdown();
    }

    public PutTakeTest(int capacity, int npairs, int ntrials) {
        this.bb = new SemaphoreBoundedBuffer<Integer>(capacity);
        this.nTrials = ntrials;
        this.nPairs = npairs;
        this.barrier = new CyclicBarrier(npairs * 2 + 1);
    }

    void test() {
        try {
            for (int i = 0; i < nPairs; i++) {
                pool.execute(new Producer());
                pool.execute(new Consumer());
            }
            barrier.await(); // wait for all threads to be ready
            barrier.await(); // wait for all threads to finish
            assertEquals(putSum.get(), takeSum.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    static int xorShift(int y) {
        y ^= (y << 6);
        y ^= (y >>> 21);
        y ^= (y << 7);
        return y;
    }

    class Producer implements Runnable {
        public void run() {
            try {
                int seed = (this.hashCode() ^ (int) System.nanoTime());
                int sum = 0;
                barrier.await();
                for (int i = nTrials; i > 0; --i) {
                    bb.put(seed);
                    sum += seed;
                    seed = xorShift(seed);
                }
                putSum.getAndAdd(sum);
                barrier.await();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    class Consumer implements Runnable {
        public void run() {
            try {
                barrier.await();
                int sum = 0;
                for (int i = nTrials; i > 0; --i) {
                    sum += bb.take();
                }
                takeSum.getAndAdd(sum);
                barrier.await();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}