并发库学习笔记五

并发流程控制   CountDownLatch 

 public void test() {

final int COUNT = 10;

final CountDownLatch countDownLatch = new CountDownLatch(COUNT);

for (int i = 0; i < COUNT; i++) {

Thread thread = new Thread("work Thread" + i) {

@Override

public void run() {

// 当你启动了一个线程,需要等到他结束

countDownLatch.countDown();

}

};

thread.start();

}

try {

countDownLatch.await();

catch (InterruptedException e) {

e.printStackTrace();

}

}

public void test2() throws InterruptedException {

final CountDownLatch startLatch = new CountDownLatch(1);

for (int i = 0; i < 10; i++) {

Thread thread = new Thread("work Thread" + i) {

@Override

public void run() {

try {

//当你启动很多线程, 你需要这些线程在等到通知后才真正可始

startLatch.await();

catch (InterruptedException e) {

e.printStackTrace();

}

}

};

thread.start();

}

startLatch.countDown();

}

 

并发流程控制

public class performaceTest {

private int threadCount;

private CyclicBarrier barrier;

private int loopCount = 10;

public void PerformaceTest(int threadCount) {

this.threadCount = threadCount;

barrier = new CyclicBarrier(threadCount, new Runnable() {

@Override

public void run() {

collectTestResult();

}

});

for (int i = 0; i < threadCount; i++) {

Thread thread = new Thread("test-thread" + i) {

@Override

public void run() {

for (int j = 0; j < loopCount; j++) {

doTest();

try {

                               //使用Barrler来实现并发性能测试的聚合点

barrier.wait();

catch (InterruptedException e) {

e.printStackTrace();

}

}

}

};

}

}

// 以下是doxx方法

private void doTest() {}

private void collectTestResult() {}

}

使用定时器

定时线程池服务

Executors ScheduledExecutorService 的工厂类,你可以创建你需要的线程池

1.5 以后就不建议使用java.util.Timer,因为他性能不如ScheduledExecutorService

大规模定时器TimerWheel

 timerWheel这个算法最早设计用来实现BSD内核中定时器的,后来被广泛应用到

ACE 框架中 是BSD算法中的经典

并发的三大定律

 Amdahl定律

   Gene Amdahl 发现在计算机体系架构设计过程中,某个部件的优化对整个架构的优化和改善是有上限的

Gustafson定律

 Gustafson假设随着处理器个数的增加,并行与串行的计算总数量也是可以增加的,认为加速系数几乎跟处理器个数成正比

 Sun-Ni定律

 充分利用存储空间等计算资源,尽量增大问题规模以产生更好/更精确的解 线程操作的方法

Start   启动一个线程实例,执行run方法

Join    一直阻塞直到其他线程退出

Interrupt  中断其他线程,线程如果在一个方法中被阻塞,会对interrupt操作做出回应,并在这个方法执行的过程中抛出interrupException,否则线程中的中断状态被设定

Stop suspend resume destory  这些不应该使用,应该使用interrupt()或者volatile标示告诉线程下一步该作什么

“未捕获异常”处理器,对没有捕获的异常进行处理

Thread thread = new Thread(new Runnable() {

@Override

public void run() {

// 操作方法

}

});

thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {

public void uncaughtException(Thread t, Throwable e) {

//在此对没有捕获的异常进行处理

}

});

thread.start();

死锁

最容易导致死锁的对象monitor,阻塞wait()notify()也容易产生死锁

饥饿

Starvation是因为一个线程长时间占用锁而导致其他线程一直处于等待状态

活锁

liveLoce 线程花费大量资源来处理协调资资源的访问,而没有真正的干活

线程协作

Wait/notify 用于一个线程通知另一个线程所需的条件状态已就绪,最常用到线程在循环中休眠,直到获取特定条件的场景

示例代码如下:

public class Latch {

private final Object lock = new Object();

private volatile boolean flag = false;

public void waitTillChange() {

synchronized (lock) {

while (!flag) {

try {

lock.wait();

catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

public void change() {

synchronized (lock) {

flag = true;

lock.notifyAll();

}

}

}

注:wait notify notifyAll 必须在synchronized修饰的代码块中执行,否则会抛出

IllegalMonitorStateException异常

   在循环条件wait的时候一定要设定循环的条件

   保证在调用notifynotifyAll之前,提供符合线程退出等待的权限

高级并发对象

Lock对象

执行器rnnable对象

并发集合 BlockingQueue  concurrentMap   ConcurrentNavigableMap

原子变量 

同步器 semaphores  mutexes  barriers  latches

锁同步法

比较并交换(compare And sparc)

CAS包括三个操作:内存位置(V) 预期原值(A)和新值(B

CAS 的并发算法,称为无锁算法

posted @ 2012-09-28 16:43  retacn_yue  阅读(201)  评论(0编辑  收藏  举报