【JAVA并发编程实战】10、并发程序的测试
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、并发程序的测试的更多相关文章
- Java并发编程实战 01并发编程的Bug源头
摘要 编写正确的并发程序对我来说是一件极其困难的事情,由于知识不足,只知道synchronized这个修饰符进行同步. 本文为学习极客时间:Java并发编程实战 01的总结,文章取图也是来自于该文章 ...
- Java并发编程实战笔记—— 并发编程1
1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread { static class MyThread1 e ...
- JAVA 基础编程练习题10 【程序 10 自由落体】
10 [程序 10 自由落体] 题目:一球从 100 米高度自由落下,每次落地后反跳回原高度的一半:再落下,求它在 第 10 次落地时, 共经过多少米?第 10 次反弹多高? package cska ...
- 《JAVA并发编程实战》示例程序第一、二章
第一章:简介 程序清单1-1非线程安全的数值序列生成器 import net.jcip.annotations.NotThreadSafe; @NotThreadSafe public class U ...
- 《JAVA并发编程实战》示例程序 第三章
3.1 可见性 程序清单3-1 在没有同步的情况下共享变量(不要这么做) /** * 主线程和读线程都将访问共享变量:ready 和 number * 结果可能 * 1. 主线程先运行完,读线程后运行 ...
- Java并发编程实战笔记—— 并发编程4
1.同步容器类 同步容器类都是线程安全的,但在某些情况下可能需要额外的客户端加锁保护复合操作. 容器上常见的复合操作包括但不限于:迭代(反复访问数据,直到遍历完容器中所有的元素为止).跳转(根据指定顺 ...
- Java并发编程实战笔记—— 并发编程2
1.ThreadLocal Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作.因此,尽管有两个线程同时执行一段相同的代码,而且这段代码又有一个指向同一个ThreadL ...
- Java并发编程实战笔记—— 并发编程3
1.实例封闭 class personset{ private final Set<Person> myset = new HashSet<Person>(); public ...
- Java并发编程实战 04死锁了怎么办?
Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...
- Java并发编程实战 05等待-通知机制和活跃性问题
Java并发编程系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 Java并发编程实 ...
随机推荐
- Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2)
Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2) 上一篇里介绍了Color-Coded Picking的思路和最基本的实现.在处理GL_POINTS时已经没有问题,但是处 ...
- zookeeper分布式锁实现
1.定义分布式锁接口 package com.ljq.lock; import java.util.concurrent.TimeUnit; public interface DistributedL ...
- 如何用TDR来测试PCB板的线路阻抗
隔壁小王已经讲了TDR的原理以及如何确定TDR的分辨率.那么,我们要正确测量PCB板上的线路阻抗,还有哪些需要注意的地方呢? 1. 阻抗测试的行业标准 之前贴过好多张阻抗测试的图片,重新再贴一张给大家 ...
- Fig 应用编排
Fig是Docker的应用编排工具,主要用来跟 Docker 一起来构建基于 Docker 的复杂应用,Fig 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景. 说 ...
- HttpResponseMessage 调用.net web api
// // GET: /Home/ //释迦苦僧 public ActionResult Index() { HttpClient client = new HttpClient(); client. ...
- 关于angularjs中的jQuery
关于angularjs中的jQuery 下面是一个小例子,用来说明我经常看到的一种模式.我们需要一个开关型的按钮.(注意:这个例子的代码有点装逼,并且有点冗长,只是为了用来代表更加复杂一些的例子,这些 ...
- Sql Server系列:数据库操作
1 创建数据库 1.1 CREATE DATABASE语法 CREATE DATABASE database_name [ ON [ PRIMARY ] <filespec> [ ,... ...
- PHP浅复制与深复制
原文链接:http://www.orlion.ga/731/ php用clone复制对象有一个问题,下面用代码来说明问题: class Foo{ public $bar; public $name; ...
- 爆一个VS2015 Update1更新带来的编译BUG【已有解决方案】
一个编译的BUG,在原生的VS2015中没有问题,但更新至VS2015 Update1之后就有了,大概是Update1用了新的编译器,害得我好苦.经测试,VS2013 Update5中也存在这个问题, ...
- EntityFramework 7.0之初探【基于VS 2015】(十)
前言 本篇作为EF 7.0的开篇也是Entity Framework目前系列末篇,因为关于EF 7.0学习资料实在是太少,我都是参考老外的资料花费了不少时间去研究去尝试同时也失败多次,个人觉得那是值得 ...