Java中有个类是CyclicBarrier,这个类是用于多线程同步的工具类。
这个工具类的大致用途是,为等待指定的线程类的对象都到齐后才让线程各自执行各自的任务,--->换句话说,就是“人员都到期了”。
demo的整体思路是:为了体现 预备条件全部具备才去"做某事" 笔者将在两个线程的run方法中分别在List<Integer>集合中放置整数。
那么到时候,从集合List<Integer> 里面去取数据做求和。如果没有数据List是会跑异常的。但是我们的CyclicBarrier设置了只有之前的两个线程全部执行完毕,
也就是在List中已设置上了数据。所以主线程取数据时,不会抛出异常。
package hello;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo
{
static List<Integer> list = new ArrayList<>();
static int result;
public static void main(String[] args)
{
/**
* 这个构造方法第二个参数可以接受一个实现了Runnable接口的对象。
* 该对象可以在所有指定的线程进入等待后,
*/
CyclicBarrier cyclicBarrier = new CyclicBarrier( 2, () ->
{
System.out.println( "在所有的线程进入等待,而未被唤醒的时机得到调用" );
result = list.get( 0 ) + list.get( 1 );
System.out.println( result );
} );
MyThread myThread1 = new MyThread( cyclicBarrier );
MyThread myThread2 = new MyThread( cyclicBarrier );
/**
* 线程的名称是----> 线程1号
*/
Thread thread1 = new Thread( myThread1, "线程1号" );
/**
* 线程的名称是----> 线程2号
*/
Thread thread2 = new Thread( myThread2, "线程2号" );
thread1.start();
thread2.start();
}
}
class MyThread implements Runnable
{
CyclicBarrier cyclicBarrier;
public MyThread(CyclicBarrier cyclicBarrier)
{
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run()
{
System.out.println( "线程:" + Thread.currentThread().getName() + "进入等待" );
/**
* 线程的名字如果是 线程1号,则让其睡眠10秒钟。为了体现线程类的对象都到齐,这个条件
*/
if(Thread.currentThread().getName().equals( "线程1号" ))
{
try
{
Thread.sleep( 10000 );
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
int randomValue = new Random().nextInt( 100 );
System.out.println( Thread.currentThread().getName() + "随机值是" + randomValue );
CyclicBarrierDemo.list.add( randomValue );
try
{
/**
* cyclicBarrie对象产生一个计数,当技术达到CyclicBarrier对象的构造方法里写的2时,即为达到所有的线程都已"就绪"的条件。
*/
cyclicBarrier.await();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
catch(BrokenBarrierException e)
{
e.printStackTrace();
}
System.out.println( "线程:" + Thread.currentThread().getName() + "被唤醒" );
}
}