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. JavaScript面试时候的坑洼沟洄——逗号、冒号与括号

    看完了javaScript数据类型和表达式与运算符相关知识后以为可以对JavaScript笔试题牛刀小试一把了,没想到有一次次的死在逗号,冒号和括号上,不得已再看看这几个符号吧. 逗号 逗号我们常见的 ...

  2. let命令

    基本用法 ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. 上面代码在代码块之中,分别用let和var声明了两个变量.然后在代码块之外调 ...

  3. js动态给当前点击元素添加css类

    1.页面:

  4. ES6 - Note6:Set与Map

    Set和Map是ES6中新增的数据结构,Set是集合,无序唯一,Map类似于对象,也是"key-value"形式,但是key不局限于字符串. 1.Set的用法 Set是构造函数,可 ...

  5. stm32控制电机

    一.总体思路       使用端口GPIOA来连接电机,所以给GPIOA编程就可以控制电机.使用系统时钟SysTick来周期性的给电机发送脉冲.用四个按钮来控制需要发送脉冲的个数,每个按钮被按下就设置 ...

  6. npm上传自己的项目

    npm安装就不介绍了,自行度娘.本文介绍npm上传 先初始化:npm init 根据提示填完系统介绍信息(package.json): 再登录npmjs: npm login 效果如图: 输入注册的用 ...

  7. CSS3动画几个平时没注意的属性

    一.timing-function: steps() 一开始在使用CSS3的时候并没有太注意这个timing-function,只是注意到自定义贝塞尔曲线. 1)一个项目中的实例 先来看看左边加了st ...

  8. JavaScript中typeof、toString、instanceof、constructor与in

    JavaScript 是一种弱类型或者说动态语言.这意味着你不用提前声明变量的类型,在程序运行过程中,类型会被自动确定. 这也意味着你可以使用同一个变量保存不同类型的数据. 最新的 ECMAScrip ...

  9. Java位运算总结-leetcode题目

    按位操作符只能用于整数基本数据类型中的单个bit中,操作符对应表格: Operator Description & 按位与(12345&1=1,可用于判断整数的奇偶性) | 按位或 ^ ...

  10. git开发流程、常用命令及工具、TortoiseGit使用及常见问题

    根据我最近使用git的一些经历,git是基于分支的版本控制工具,分支有远程分支和本地分支. 一.开发流程 - 从远程服务器的master,clone一份项目文件到本地,然后本地master的基础上br ...