【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并发编程实 ...
随机推荐
- JavaScript字符串排序localeCompare()笔记
今天遇到了一个没有接触过的方法,是localeCompare().查了一些相关的文档,给出的定义很模糊,所以就把自己的理解写下来. 首先由例子入手! 已知一串学生姓名的字符串,根据学生姓名的长度按照降 ...
- PHP面向对象
面向对象 1.类由众多的对象抽象出来的 2.对象 一起皆对象 由类实例化出来的 求两个圆之间阴影的面积 $sr1=10; $sr2=5; $mj=3.14*$sr1*$sr1-3.1 ...
- CentOS7安装mysql提示“No package mysql-server available.”
针对centos7安装mysql,提示"No package mysql-server available."错误,解决方法如下: Centos 7 comes with Mari ...
- VMware Workstation and Hyper-V are not compatible. 解决方案
VMware 和 Hyper-V 不能共存问题报错如下:VMware Workstation and Hyper-V are notcompatible. Remove the Hyper-V rol ...
- 【转】WPF防止界面卡死并显示加载中效果
原文地址:http://www.cnblogs.com/linyijia/archive/2013/02/06/2900609.html <Window x:Class="Loadin ...
- Spark中决策树源码分析
1.Example 使用Spark MLlib中决策树分类器API,训练出一个决策树模型,使用Python开发. """ Decision Tree Classifica ...
- 【开源】OSharp3.3框架解说系列:开发计划与进度
OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...
- Windws Server 2008 R2 WEB环境配置之MYSQL 5.6.22安装配置
版本选择 因为MySql的版本越来越多,而作为中小网站者可能没有足够的经济去购买商业版本,所以一般选择免费版,而且功能也是足够使用的. 有钱任性就下载企业版,哈哈. 目前使用最多的版本是mysql i ...
- Microsoft.Office.Interop.Excel的用法以及利用Microsoft.Office.Interop.Excel将web页面转成PDF
1.常见用法 using Microsoft.Office.Interop.Excel; 1)新建一个Excel ApplicationClass ExcelApp = New A ...
- C语言 第一章 C语言简介
一.C语言介绍 C是一种通用的编程语言,广泛用于系统软件与应用软件的开发.于1969年至1973年间,为了移植与开发UNIX操作系统,由丹尼斯·里奇与肯·汤普逊,以B语言为基础,在贝尔实验室设计.开发 ...