1.CountDownLauth用法
public class MyCountDownLauth {
private static Integer count = 20;
final static CountDownLatch countDownLatch = new CountDownLatch(count);
public static void main(String[] args) {
for (int i = 0; i < count; i++) {
new Test(i, countDownLatch){
}.start();
countDownLatch.countDown();
}
}
static class Test extends Thread{
private Integer i;
private CountDownLatch countDownLatch;
public Test(Integer i ,CountDownLatch countDownLatch) {
super();
this.i = i;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
countDownLatch.await();
System.out.println("第"+i+"个线程启动");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这个作用是让线程先等待,然后同时运行,相当于发令枪
public class MyCountDownLauth2 {
private static Integer count = 2;
public static void main(String[] args) {
final CountDownLatch countDownLatch = new CountDownLatch(count);
new Thread(){
public void run() {
try {
Thread.sleep(1000);
System.out.println("第一个线程启动");
countDownLatch.countDown();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
new Thread(){
public void run() {
try {
Thread.sleep(1000);
System.out.println("第二个线程启动");
countDownLatch.countDown();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
try {
countDownLatch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("主线程启动");
}
}
作用是在所有线程执行完之后执行某个方法
CountDownLauth中的构造函数的state为0是,执行countDown()方法之后还是0,执行await()方法不会等待
2.CyclicBarrier用法
public class MyCyclicBarrier {
public static void main(String[] args) {
int N = 4;
CyclicBarrier barrier = new CyclicBarrier(N);
for(int i=0;i<N;i++){
new Writer(barrier).start();
}
}
static class Writer extends Thread{
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");
try {
Thread.sleep(5000);
System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
System.out.println("所有线程写入完毕,继续处理其他任务...");
}
}
}
构造函数中的参数parties是线程的数量,当所有线程都进入等待或者有一个线程的等待时间到了之后所有线程同时继续进行,
其中await()方法可以带参也可以不带参,参数是等待的时间和时间单位,调await()方法会让一个线程处于等待,再调用一次会使下一个线程进入等待,如果某一个线程的等待时间到了但还有线程没有进入等待的话,那个线程就会抛出TimeoutException异常。
当CyclicBarrier执行完parties次await()后,仍可继续执行await()方法,并重新计数
CyclicBarrier还有另一个构造函数
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}
barrierAction中的run()方法将在一次循环结束后执行
3.Semaphore用法
public class MySemaphore {
private static int RESOURCE = 5;
private static int CONSUMERS = 8;
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(RESOURCE);
for (int i = 0; i < CONSUMERS; i++) {
new Consume(i, semaphore).start();
}
}
static class Consume extends Thread{
private int num;
private Semaphore semaphore;
public Consume(int num, Semaphore semaphore){
super();
this.num = num;
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("消费者" + num + "获得资源...");
Thread.sleep(2000);
System.out.println("消费者" + num + "释放资源");
semaphore.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Semaphore主要用来中的主要方法有以下:
void
acquire()//获得一个许可
void
acquire(
int
permits)//获得permits个许可
void
release()//释放一个许可
void
release(
int
permits)//释放permits个许可
boolean
tryAcquire() { };//尝试获得一个许可,获得后返回true,没有获得返回false
boolean tryAcquire(long
timeout, TimeUnit unit)//尝试获得一个许可,在指定时间内获得后返回true,没有获得返回false
boolean tryAcquire(int
permits) { };//尝试获得permits个许可,获得后返回true,没有获得返回false
boolean tryAcquire(int
permits,
long
timeout, TimeUnit unit)//尝试获得permits个许可,在指定时间内获得后返回true,没有获得返回false
4.Exchanger用法
Exchanger用于两个线程交换相同类型的数据
public class MyExchanger {
public static void main(String[] args) {
final Exchanger<List<String>> exchanger = new Exchanger<List<String>>();
new Thread(){
@Override
public void run() {
List<String> l1 = new ArrayList<String>();
l1.add("aaa");
l1.add("bbb");
try {
l1 = exchanger.exchange(l1);
System.out.println("l1:"+l1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
new Thread(){
@Override
public void run() {
List<String> l2 = new ArrayList<String>();
l2.add("ccc");
l2.add("ddd");
try {
l2 = exchanger.exchange(l2);
System.out.println("l2:"+l2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
}
Exchanger还有另一个重载的exchange方法
public V exchange(V x, long timeout, TimeUnit unit)
在指定时间内没有交换数据就会报错
public class MyExchanger2 {
public static void main(String[] args) {
final Exchanger<List<String>> exchanger = new Exchanger<List<String>>();
new Thread(){
@Override
public void run() {
List<String> l1 = new ArrayList<String>();
l1.add("aaa");
l1.add("bbb");
try {
l1 = exchanger.exchange(l1, 2000, TimeUnit.MILLISECONDS);
System.out.println("l1:"+l1);
} catch (InterruptedException e) {
e.printStackTrace();
}
catch (TimeoutException e) {
e.printStackTrace();
}
}
}.start();
}
}