多线程成对特性

http://www.cnblogs.com/skywang12345/p/java_threads_category.html
http://www.itzhai.com/category/server-side/j2ee/java


join() 方法主要是让调用该方法的thread完成run方法里面的东西后, 在执行join()方法后面的代码,指在一线程里面调用另一线程join方法时,表示将本线程阻塞直至另一线程终止时再执行 。

Callable和Future
wait(),和notify()、notifyAll()
如果说CountDownLatch是一次性的,那么CyclicBarrier正好可以循环使用。它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。所谓屏障点就是一组任务执行完毕的时刻。



Java之CyclicBarrier使用
1、类说明:
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

2、使用场景:
需要所有的子任务都完成时,才执行主任务,这个时候就可以选择使用CyclicBarrier。

CountDownLatch,先await,如果递减countDown到0才执行await后面的,CountDownLatch类是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞程序继续执行
CountDownLatch如其所写,是一个倒计数的锁存器,当计数减至0时触发特定的事件。利用这种特性,可以让主线程等待子线程的结束。下面以一个模拟运动员比赛的例子加以说明。

首先,CyclicBarrier可以多次使用,CountDownLatch只能用一次(为0后不可变)
其次,
Barrier是等待指定数量线程到达再继续处理;
Latch是等待指定事件变为指定状态后发生再继续处理,对于CountDown就是计数减为0的事件,但你也可以实现或使用其他Latch就不是这个事件了...

Barrier是等待指定数量任务完成,Latch是等待其他任务完成指定状态的改变再继续。。

CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。   CyclicBarrier        : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。




CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数一样, 只不过是递减的.

而CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.




package com.thread;

import java.io.IOException;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CyclicBarrierTest {

	public static void main(String[] args) throws IOException, InterruptedException {
		//如果将参数改为4,但是下面只加入了3个选手,这永远等待下去
		//Waits until all parties have invoked await on this barrier. 
		CyclicBarrier barrier = new CyclicBarrier(3);

		ExecutorService executor = Executors.newFixedThreadPool(3);
		executor.submit(new Thread(new Runner(barrier, "1号选手")));
		executor.submit(new Thread(new Runner(barrier, "2号选手")));
		executor.submit(new Thread(new Runner(barrier, "3号选手")));

		executor.shutdown();
	}
}

class Runner implements Runnable {
	// 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)
	private CyclicBarrier barrier;

	private String name;

	public Runner(CyclicBarrier barrier, String name) {
		super();
		this.barrier = barrier;
		this.name = name;
	}

	@Override
	public void run() {
		try {
			Thread.sleep(1000 * (new Random()).nextInt(8));
			System.out.println(name + " 准备好了...");
			// barrier的await方法,在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
			//System.out.println(barrier.getNumberWaiting()+1);
			if(barrier.getParties() == (barrier.getNumberWaiting()+1)){
				System.out.println("all over");
			}
			barrier.await();
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
		System.out.println(name + " 起跑!");
	}
}





package com.thread;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

// 一个CountDouwnLatch实例是不能重复使用的,也就是说它是一次性的,锁一经被打开就不能再关闭使用了,如果想重复使用,请考虑使用CyclicBarrier。
public class CountDownLatchTest {

    // 模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。
    public static void main(String[] args) throws InterruptedException {
    	final int nums = 10;
    	
        // 开始的倒数锁 
        final CountDownLatch begin = new CountDownLatch(1);  

        // 结束的倒数锁 
        final CountDownLatch end = new CountDownLatch(nums);  

        // 十名选手 
        final ExecutorService exec = Executors.newFixedThreadPool(nums);  

        for (int index = 0; index < nums; index++) {
            final int NO = index + 1;  
            Runnable run = new Runnable() {
                public void run() {  
                    try {  
                        begin.await();  // 等待,后面不会执行,只有begin变为0后才执行
                        Thread.sleep((long) (Math.random() * 10000));  
                        System.out.println("No." + NO + " arrived");  
                    } catch (InterruptedException e) {  
                    } finally {  
                        end.countDown();// 每个选手到达终点时,end就减一,直到总的10减为0
                    }  
                }  
            };  
            exec.execute(run);
        }  
        System.out.println("Game Start");  
        begin.countDown();  //begin减一,begin从1到0,开始游戏
        end.await();  // 等待end变为0,即所有选手到达终点
        System.out.println("Game Over");  
        exec.shutdown();  
    }
}

猜你喜欢

转载自sunwtrain.iteye.com/blog/2142806
今日推荐