当我们需要多个线程同时启动时,我们可以使用jdk自带的CycliBarrier。先来看看它的常用用法:
package com.my.CuratorTest;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* Title: <br/>
* Intention: <br/>
* <p>
* Class Name: com.my.CuratorTest.CycliBarrierTest<br/>
* Create Date: 2017/8/26 11:18 <br/>
* Project Name: MyTest <br/>
* Company: All Rights Reserved. <br/>
* Copyright © 2017 <br/>
* </p>
* <p>
* author: GaoWei <br/>
* 1st_examiner: <br/>
* 2nd_examiner: <br/>
* </p>
*
* @version 1.0
* @since JDK 1.7
*/
public class CycliBarrierTest {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(5);
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+", 等待...");
try {
barrier.await();
System.out.println(Thread.currentThread().getName()+ ", " + System.currentTimeMillis() + ", 开始工作");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
运行结果:
Thread-3, 等待...
Thread-1, 等待...
Thread-0, 等待...
Thread-2, 等待...
Thread-4, 等待...
Thread-4, 1503736464892, 开始工作
Thread-3, 1503736464892, 开始工作
Thread-0, 1503736464892, 开始工作
Thread-1, 1503736464892, 开始工作
Thread-2, 1503736464892, 开始工作
那么,在分布式环境下如何解决多个线程同时启动的问题呢?Curator为我们提供了DistributedBarrier(主线程触发barrier释放) 和 DistributedDoubleBarrier(线程自发触发barrier释放)。
DistributedBarrier的使用如下,拷贝书上代码:
package com.my.CuratorTest;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.barriers.DistributedBarrier;
import org.apache.curator.retry.ExponentialBackoffRetry;
/**
* Title: <br/>
* Intention: <br/>
* <p>
* Class Name: com.my.CuratorTest.RecipesBarrier<br/>
* Create Date: 2017/8/26 11:07 <br/>
* Project Name: MyTest <br/>
* Company: All Rights Reserved. <br/>
* Copyright © 2017 <br/>
* </p>
* <p>
* author: GaoWei <br/>
* 1st_examiner: <br/>
* 2nd_examiner: <br/>
* </p>
*
* @version 1.0
* @since JDK 1.7
*/
public class RecipesBarrier {
static String barrierPath = "/curator_recipes_barrier_path";
static DistributedBarrier barrier;
public static void main(String[] args) throws Exception {
for(int i=0;i<5;i++) {
new Thread(new Runnable() {
@Override
public void run() {
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("127.0.0.1:2181")
.retryPolicy(new ExponentialBackoffRetry(1000, 8))
.build();
client.start();
barrier = new DistributedBarrier(client, barrierPath);
System.out.println(Thread.currentThread().getName() + "号barrier设置");
try {
barrier.setBarrier();
barrier.waitOnBarrier();
System.err.println(Thread.currentThread().getName() + " 启动...");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
Thread.sleep(2000);
barrier.removeBarrier();
}
}
运行结果:
Thread-4号barrier设置
Thread-2号barrier设置
Thread-3号barrier设置
Thread-0号barrier设置
Thread-1号barrier设置
Thread-3 启动...
Thread-4 启动...
Thread-2 启动...
Thread-0 启动...
Thread-1 启动...
DistributedDoubleBarrier的使用如下:
package com.my.CuratorTest;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.barriers.DistributedDoubleBarrier;
import org.apache.curator.retry.ExponentialBackoffRetry;
/**
* Title: <br/>
* Intention: <br/>
* <p>
* Class Name: com.my.CuratorTest.RecipesBarrier2<br/>
* Create Date: 2017/8/26 16:05 <br/>
* Project Name: MyTest <br/>
* Company: All Rights Reserved. <br/>
* Copyright © 2017 <br/>
* </p>
* <p>
* author: GaoWei <br/>
* 1st_examiner: <br/>
* 2nd_examiner: <br/>
* </p>
*
* @version 1.0
* @since JDK 1.7
*/
public class RecipesBarrier2 {
static String barrierPath = "/curator_recipes_barrier_path";
public static void main(String[] args) {
for (int i = 0; i < 5; i ++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("127.0.0.1:2181")
.retryPolicy(new ExponentialBackoffRetry(1000, 3))
.build();
client.start();
DistributedDoubleBarrier barrier = new DistributedDoubleBarrier(client, barrierPath, 5);
Thread.sleep(Math.round(Math.random() * 3000));
System.out.println(Thread.currentThread().getName() +" 号进入barrier");
barrier.enter();
System.out.println(Thread.currentThread().getName() +" 启动...");
Thread.sleep(Math.round(Math.random() * 3000));
barrier.leave();
System.out.println(Thread.currentThread().getName() +" 退出...");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
运行结果:
Thread-2 号进入barrier
Thread-1 号进入barrier
Thread-4 号进入barrier
Thread-0 号进入barrier
Thread-3 号进入barrier
Thread-3 启动...
Thread-4 启动...
Thread-1 启动...
Thread-0 启动...
Thread-2 启动...
Thread-2 退出...
Thread-4 退出...
Thread-0 退出...
Thread-1 退出...
Thread-3 退出...