1、产生随机数
package cn.study.concurrency.ch12;
public class Util {
public static int xorShift(int y)
{
//进行左移和无符号右移,最后异或操作(异或,当两个位数据不同的时候为1,否则为0)
y ^= (y << 6);
y ^= (y >>> 21);
y ^= (y << 7);
return y;//y初始值是随机种子
}
public static void main(String[] args) {
for(int i = 0; i < 10; ++i)
{
System.out.println(xorShift((int) System.nanoTime()));
}
}
}
2、缓存队列
package cn.study.concurrency.ch12;
import java.util.concurrent.Semaphore;
public class BoundedBuffer<E> {
//信号量
private final Semaphore availableItems, availableSpaces;
private final E[] items;
private int putPosition=0, takePosition=0;
public BoundedBuffer(int capacity)
{
availableItems = new Semaphore(0);
availableSpaces = new Semaphore(capacity);
items = (E[]) new Object[capacity];
}
public boolean isEmpty()
{
//这个表示已经是空的了
return availableItems.availablePermits() == 0;
}
public boolean isFull()
{
//表明这个是满的队列
return availableSpaces.availablePermits() == 0;
}
//放入一个对象,首先向availableSpaces请求一个信号量,然后结束之后返回一个availableItems信号
public void put(E x) throws InterruptedException
{
//减少一个许可
availableSpaces.acquire();
doInsert(x);
//添加一个许可
availableItems.release();
}
//释放一个数据对象
public E take() throws InterruptedException
{
//当释放一个对象的时候,减少一个连接许可
availableItems.acquire();
E item = doExtract();
availableSpaces.release();//取出数据之后,吧能插入的可能添加一个
return item;
}
private synchronized void doInsert(E x)
{
int i = putPosition;
items[i] = x;
putPosition = (++i == items.length) ? 0 : i;
}
//不论是取数据,还是获取数据,都是循环取得
private synchronized E doExtract()
{
int i = takePosition;
E x = items[i];
items[i] = null;
takePosition = (++i == items.length) ? 0: i;
return x;
}
public static void main(String[] args) throws InterruptedException {
BoundedBuffer<Integer> bb = new BoundedBuffer<Integer>(10);
bb.take();
if(bb.isEmpty())
{
System.out.println("空");
}
if(bb.isFull())
{
System.out.println("满");
}
}
}
3、测试方法
package cn.study.concurrency.ch12;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class PutTakeTest {
//创建线程池
private static final ExecutorService pool = Executors.newCachedThreadPool();
//原子型的int数据,最后用来统计线程设计是否合理,是否线程安全
private final AtomicInteger putSum = new AtomicInteger(0);
private final AtomicInteger takeSum = new AtomicInteger(0);
private final CyclicBarrier barrier; //栅栏
private final BoundedBuffer<Integer> bb; //队列
private final int nTrials, nPairs; //要创建的队列数量和栅栏的屏障点
//构造函数
public PutTakeTest(int capacity, int npairs, int ntrials) {
this.bb = new BoundedBuffer<Integer>(capacity);
this.nTrials = ntrials;
this.nPairs = npairs;
//+1是为了,在所有的线程都建立结束之后,最后编码手动决定什么时候启动所有线程
this.barrier = new CyclicBarrier(2 * npairs + 1);
}
//生产者线程
class Producer implements Runnable
{
@Override
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 = Util.xorShift(seed);//获取随机值
}
//获取值,并且添加到putsum中
putSum.getAndAdd(sum);
barrier.await();//添加一个栅栏,标识运行结束
} catch (Exception e) {
System.out.println("????producer");
}
}
}
//消费者线程
class Consumer implements Runnable
{
@Override
public void run() {
try {
barrier.await();//进行栅栏等待
int sum = 0;
for(int i = nTrials; i > 0; --i)
{
sum += bb.take();
}
//获取值,并且添加到putsum中
takeSum.getAndAdd(sum);
barrier.await();//添加一个栅栏,标识运行结束
} catch (Exception e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getName() + "????consumer");
}
}
}
//测试函数
public void test()
{
try {
for(int i = 0; i < nPairs; ++i)
{
pool.execute(new Producer());
pool.execute(new Consumer());
}
//当现场全部添加好了之后,打开栅栏
barrier.await(); //第2n+1个
//然后线程执行之后,每个线程执行完又调用了一次await,当所有的都执行完了之后
barrier.await();
//全部结束之后判断是否结果对等
if(putSum.get() == takeSum.get())
{
System.out.println("程序是OK的");
}
else
{
System.out.println("程序有安全漏洞");
}
} catch (Exception e) {
System.out.println("????test");
}
}
public static void main(String[] args) {
//队列容量是10,每个线程起10个,一共放100000个数据
new PutTakeTest(10, 2, 100).test();
pool.shutdown();//执行完,结束线程
}
}