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();//执行完,结束线程
}
}

【JAVA并发编程实战】10、并发程序的测试的更多相关文章

  1. Java并发编程实战 01并发编程的Bug源头

    摘要 编写正确的并发程序对我来说是一件极其困难的事情,由于知识不足,只知道synchronized这个修饰符进行同步. 本文为学习极客时间:Java并发编程实战 01的总结,文章取图也是来自于该文章 ...

  2. Java并发编程实战笔记—— 并发编程1

    1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread { static class MyThread1 e ...

  3. JAVA 基础编程练习题10 【程序 10 自由落体】

    10 [程序 10 自由落体] 题目:一球从 100 米高度自由落下,每次落地后反跳回原高度的一半:再落下,求它在 第 10 次落地时, 共经过多少米?第 10 次反弹多高? package cska ...

  4. 《JAVA并发编程实战》示例程序第一、二章

    第一章:简介 程序清单1-1非线程安全的数值序列生成器 import net.jcip.annotations.NotThreadSafe; @NotThreadSafe public class U ...

  5. 《JAVA并发编程实战》示例程序 第三章

    3.1 可见性 程序清单3-1 在没有同步的情况下共享变量(不要这么做) /** * 主线程和读线程都将访问共享变量:ready 和 number * 结果可能 * 1. 主线程先运行完,读线程后运行 ...

  6. Java并发编程实战笔记—— 并发编程4

    1.同步容器类 同步容器类都是线程安全的,但在某些情况下可能需要额外的客户端加锁保护复合操作. 容器上常见的复合操作包括但不限于:迭代(反复访问数据,直到遍历完容器中所有的元素为止).跳转(根据指定顺 ...

  7. Java并发编程实战笔记—— 并发编程2

    1.ThreadLocal Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作.因此,尽管有两个线程同时执行一段相同的代码,而且这段代码又有一个指向同一个ThreadL ...

  8. Java并发编程实战笔记—— 并发编程3

    1.实例封闭 class personset{ private final Set<Person> myset = new HashSet<Person>(); public ...

  9. Java并发编程实战 04死锁了怎么办?

    Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...

  10. Java并发编程实战 05等待-通知机制和活跃性问题

    Java并发编程系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 Java并发编程实 ...

随机推荐

  1. MySQL外键之级联

    简介 MySQL外键起到约束作用,在数据库层面保证数据的完整性.例如使用外键的CASCADE类型,当子表(例如user_info)关联父表(例如user)时,父表更新或删除时,子表会更新或删除记录,这 ...

  2. 兼容各浏览器的js判断上传文件大小

    由于项目需要,在网上找了一个JS判断上传文件大小的程序,经测试兼容IE6-,Firefox10,Opera11.,safari5.,chrome17 <!DOCTYPE html> < ...

  3. JavaScript必须了解的知识点总结。

    整理的知识点不全面但是很实用. 主要分三块: (1)JS代码预解析原理(包括三个段落): (2)函数相关(包括 函数传参,带参数函数的调用方式,闭包): (3)面向对象(包括 对象创建.原型链,数据类 ...

  4. Join 和 apply 用法

    TSQL中的join语句共有五种类型,left join,right join,inner join,full join,cross join 为了描述方便,解释一个名词"保留表" ...

  5. ExtJS面向对象

    序言 1.ExtJs是一套很好的后台框架.现在很流行的,我们要会. 2.这是我写ExtJs的第一篇,以后会写很多直到把这框架运用的炉火纯青,走火入魔. ExtJs中的命名空间 我是做.net的,这命名 ...

  6. 【Win 10应用开发】认识一下UAP项目

    Windows 10 SDK预览版需要10030以上版本号的Win 10预览版系统才能使用.之前我安装的9926的系统,然后安装VS 2015 CTP 6,再装Win 10 SDK,但是在新建项目后, ...

  7. css3圆形头像(当图片宽高不相等时)

    1.图片宽高相等,width:300px: height:300px; 把他变成宽高100px的圆形头像 img{width:100px; height:100px; border-radius:50 ...

  8. @font-face使用

    转自http://www.tuicool.com/articles/QVf6nei 一.webfont与@font-face 什么是webfont web font,又称之为 在线字体 或者 网络字体 ...

  9. 【原创】机器学习之PageRank算法应用与C#实现(2)球队排名应用与C#代码

    在上一篇文章:机器学习之PageRank算法应用与C#实现(1)算法介绍 中,对PageRank算法的原理和过程进行了详细的介绍,并通过一个很简单的例子对过程进行了讲解.从上一篇文章可以很快的了解Pa ...

  10. 理解 Neutron Server 分层模型 - 每天5分钟玩转 OpenStack(69)

    本节开始讨论 Neutron 的各个服务组件,首先学习 Neutron Server . 上图是 Neutron Server 的分层结构,至上而下依次为: Core API对外提供管理 networ ...