CyclicBarrier用於設置一個Barrier,達到Barrier的線程將等待,當所有線程都達到Barrier時,所有線程繼續執行。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
1. 創建CyclicBarrier時通過構造函數指定線程的數量n。
2. 每個線程調用await方法等待其他線程。
3. 當有n個await方法被調用時,所有處於await的線程都將繼續執行。
- import java.util.concurrent.BrokenBarrierException;
- import java.util.concurrent.CyclicBarrier;
- public class CyclicBarrierTest
- {
- private static CyclicBarrier barrier = null;
- public static void main(String[] args)
- {
- // 初始化
- barrier = new CyclicBarrier(10);
- // 啓動10個線程
- System.out.println("main: starting 10 threads.");
- for (int i = 0; i < 10; i++)
- {
- Thread th = new Thread(new TestRunnable(), "thread " + i);
- th.start();
- }
- }
- private static class TestRunnable implements Runnable
- {
- @Override
- public void run()
- {
- String thName = Thread.currentThread().getName();
- try
- {
- // 隨機等待5-14秒
- int n = (int)(Math.random() * 10 + 5);
- System.out.printf("%s: sleep for %d seconds. /n", thName, n);
- Thread.sleep(n * 1000);
- // 等待其他線程
- System.out.printf("%s: waiting for other threads. /n", thName);
- barrier.await();
- // 結束
- System.out.printf("%s: end. /n", thName);
- }
- catch (InterruptedException e)
- {
- System.out.printf("%s: interrupted. /n", thName);
- return;
- }
- catch (BrokenBarrierException e)
- {
- System.out.printf("%s: broken barrier. /n", thName);
- return;
- }
- }
- }
- }
1. 在調用await方法時設置超時時間。
2. 當有一個await方法超時,所有處於await等待的線程將收到BrokenBarrierException,超時的線程自身將收到TimeoutException。
3. BrokenBarrier之後的所有await調用將直接拋出BrokenBarrierException。
- import java.util.concurrent.BrokenBarrierException;
- import java.util.concurrent.CyclicBarrier;
- import java.util.concurrent.TimeUnit;
- import java.util.concurrent.TimeoutException;
- public class CyclicBarrierBrokenTest
- {
- private static CyclicBarrier barrier = null;
- public static void main(String[] args)
- {
- // 初始化
- barrier = new CyclicBarrier(10);
- // 啓動10個線程
- System.out.println("main: starting 10 threads.");
- for (int i = 0; i < 10; i++)
- {
- Thread th = new Thread(new TestRunnable(), "thread " + i);
- th.start();
- }
- }
- private static class TestRunnable implements Runnable
- {
- @Override
- public void run()
- {
- String thName = Thread.currentThread().getName();
- try
- {
- // 隨機等待5-14秒
- int n = (int)(Math.random() * 10 + 5);
- System.out.printf("%s: sleep for %d seconds. /n", thName, n);
- Thread.sleep(n * 1000);
- // 等待其他線程
- System.out.printf("%s: waiting for other threads. /n", thName);
- barrier.await(5, TimeUnit.SECONDS);
- // 結束
- System.out.printf("%s: end. /n", thName);
- }
- catch (InterruptedException e)
- {
- System.out.printf("%s: interrupted. /n", thName);
- return;
- }
- catch (BrokenBarrierException e)
- {
- System.out.printf("%s: broken barrier. /n", thName);
- return;
- }
- catch (TimeoutException e)
- {
- System.out.printf("%s: timeout. /n", thName);
- return;
- }
- }
- }
- }
當調用await線程達到CyclicBarrier的設置之後,CyclicBarrier將被重置,重新等待n個await調用。
- import java.util.concurrent.BrokenBarrierException;
- import java.util.concurrent.CyclicBarrier;
- public class CyclicBarrierResetTest
- {
- private static CyclicBarrier barrier = null;
- public static void main(String[] args) throws Exception
- {
- barrier = new CyclicBarrier(2);
- Thread th1 = new Thread(new TestRunnable(), "thread 1");
- Thread th2 = new Thread(new TestRunnable(), "thread 2");
- th1.start();
- th2.start();
- Thread.sleep(60 * 1000);
- th1.interrupt();
- th2.interrupt();
- th1.join();
- th2.join();
- }
- private static class TestRunnable implements Runnable
- {
- @Override
- public void run()
- {
- String thName = Thread.currentThread().getName();
- System.out.printf("%s: start. /n", thName);
- try
- {
- while (true)
- {
- // 隨機產生1-100的整數。
- int c = (int)(Math.random() * 100) + 1;
- // 隨機等待0-4秒。
- int t = (int)(Math.random() * 5);
- System.out.printf("%s: sleep for %d seconds./n", thName, t);
- Thread.sleep(t * 1000);
- // 等待另1線程。
- barrier.await();
- // 輸出產生的整數。
- System.out.printf("%s: %d /n", thName, c);
- // 等待其他線程輸出。
- Thread.sleep(100);
- }
- }
- catch (InterruptedException e)
- {
- System.out.printf("%s: interrupted. /n", thName);
- }
- catch (BrokenBarrierException e)
- {
- e.printStackTrace();
- }
- System.out.printf("%s: end. /n", thName);
- }
- }
- }
1. 在創建CyclicBarrier的時候指定通過Barrier時需要執行的語句。
2. 通過構造方法的Runnable參數指定。
3. Runnable中的語句將由最後達到Barrier的線程執行。
- import java.util.concurrent.BrokenBarrierException;
- import java.util.concurrent.CyclicBarrier;
- public class CyclicBarrierActionTest
- {
- private static CyclicBarrier barrier = null;
- public static void main(String[] args) throws Exception
- {
- barrier = new CyclicBarrier(10, new BarrierAction());
- for (int i = 0; i < 10; i++)
- {
- Thread th = new Thread(new TestRunnable(), "thread " + i);
- th.start();
- }
- }
- private static class TestRunnable implements Runnable
- {
- @Override
- public void run()
- {
- try
- {
- String thName = Thread.currentThread().getName();
- // System.out.printf("%s: start. /n", thName);
- // 隨機等待0-9秒
- int t = (int)(Math.random() * 10);
- System.out.printf("%s: sleep for %d seconds. /n", thName, t);
- Thread.sleep(t * 1000);
- // 等待barrier
- barrier.await();
- System.out.printf("%s: end. /n", thName);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- return;
- }
- catch (BrokenBarrierException e)
- {
- e.printStackTrace();
- return;
- }
- }
- }
- private static class BarrierAction implements Runnable
- {
- @Override
- public void run()
- {
- String thName = Thread.currentThread().getName();
- System.out.printf("%s: barrier action. /n", thName);
- }
- }
- }