javacyclicbarrier的简单介绍
Java 多线程控制
1.用等待,第一个线程执行完毕后,再让第2个线程运行,第2个结束后,再运行第3个。有个方法Join可以利用。
2.可以
3.不能,队列只是一种数据结构,控制线程只能用线程相关的方法。
Java中用CyclicBarrier以及CountDownLatch和join相比有什么不同
第一个:用Thread.join只能部分的实现CountDownLatch的功能. 这个看看CountDownLatch的java doc就可以了.
第二个:Thread.join用了Object.wait/notify机制. java.lang.Thread.join(long millis) java doc里写道:
This implementation uses a loop of this.wait calls conditioned on
this.isAlive. As a thread terminates the this.notifyAll method is
invoked. It is recommended that applications not use wait, notify,
or notifyAll on Thread instances.
Effective Java第二版里说的很好, wait/nofify 和java.util.concurrent提供的功能比起来, 就好像是 并发汇编语言(concurrency assembly language) 一样. 更难用而且也更容易出bug.
java中cyclicbarrier 和 countdownlatch有什么不同
cyclibarriar 就是栅栏,顾名思义:就是一个拦截的装置。多个线程start后,在栅栏处阻塞住,一般定义栅栏的时候会定义有多少个线程。比如定义为4个,那么有三个线程到栅栏处,就阻塞住,如果没有第四个,就会一直阻塞,知道启动第四个线程到栅栏
java并发包有哪些类
1、CyclicBarrier
一个同步辅助类,允许一组线程相互等待,直到这组线程都到达某个公共屏障点。该barrier在释放等待线程后可以重用,因此称为循环的barrier。
来个示例:
[java]?view plain?copy
package?test;
import?java.util.concurrent.CyclicBarrier;
import?java.util.concurrent.ExecutorService;
import?java.util.concurrent.Executors;
public?class?Recipes_CyclicBarrier?{
public?static?CyclicBarrier?barrier?=?new?CyclicBarrier(10);
public?static?void?main(String[]?args){
ExecutorService?executor?=?Executors.newCachedThreadPool();//FixedThreadPool(10);
for(int?i=1;i=10;i++){
executor.submit(new?Thread(new?Runner(i+"号选手")));
}
executor.shutdown();
}
}
class?Runner?implements?Runnable{
private?String?name;
public?Runner(String?name){
this.name?=?name;
}
@Override
public?void?run()?{
System.out.println(name?+?"准备好了。");
try?{
Recipes_CyclicBarrier.barrier.await();??//此处就是公共屏障点,所有线程到达之后,会释放所有等待的线程
}?catch?(Exception?e)?{
}
System.out.println(name?+?"起跑!");
}
}
2、CountDownLatch
CountDownLatch和CyclicBarrier有点类似,但是还是有些区别的。CountDownLatch也是一个同步辅助类,它允许一个或者多个线程一直等待,直到正在其他线程中执行的操作完成。它是等待正在其他线程中执行的操作,并不是线程之间相互等待。CountDownLatch初始化时需要给定一个计数值,每个线程执行完之后,必须调用countDown()方法使计数值减1,直到计数值为0,此时等待的线程才会释放。
来个示例:
[java]?view plain?copy
package?test;
import?java.util.concurrent.CountDownLatch;
import?java.util.concurrent.CyclicBarrier;
import?java.util.concurrent.ExecutorService;
import?java.util.concurrent.Executors;
public?class?CountDownLatchDemo?{
public?static?CountDownLatch?countDownLatch?=?new?CountDownLatch(10);//初始化计数值
public?static?void?main(String[]?args){
ExecutorService?executor?=?Executors.newCachedThreadPool();//FixedThreadPool(10);
for(int?i=1;i=10;i++){
executor.submit(new?Thread(new?Runner1(i+"号选手")));
}
executor.shutdown();
}
}
class?Runner1?implements?Runnable{
private?String?name;
public?Runner1(String?name){
this.name?=?name;
}
@Override
public?void?run()?{
System.out.println(name?+?"准备好了。");
CountDownLatchDemo.countDownLatch.countDown();??//计数值减1
try?{
CountDownLatchDemo.countDownLatch.await();
}?catch?(Exception?e)?{
}
System.out.println(name?+?"起跑!");
}
}
3、CopyOnWriteArrayList CopyOnWriteArraySet
CopyOnWriteArrayList CopyOnWriteArraySet是并发容器,适合读多写少的场景,如网站的黑白名单设置。缺点是内存占用大,数据一致性的问题,CopyOnWrite容器只能保证数据最终的一致性,不能保证数据实时一致性。鉴于它的这些缺点,可以使用ConcurrentHashMap容器。
实现原理:新增到容器的数据会放到一个新的容器中,然后将原容器的引用指向新容器,旧容器也会存在,因此会有两个容器占用内存。我们也可以用同样的方式实现自己的CopyOnWriteMap。
4、ConcurrentHashMap
ConcurrentHashMap同样是一个并发容器,将同步粒度最小化。
实现原理:ConcurrentHashMap默认是由16个Segment组成,每个Segment由多个Hashtable组成,数据变更需要经过两次哈希算法,第一次哈希定位到Segment,第二次哈希定位到Segment下的Hashtable,容器只会将单个Segment锁住,然后操作Segment下的Hashtable,多个Segment之间不受影响。如果需要扩容不是对Segment扩容而是对Segment下的Hashtable扩容。虽然经过两次哈希算法会使效率降低,但是比锁住整个容器效率要高得多。
5、BlockingQueue
BlockingQueue只是一个接口,它的实现类有ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、DelayQueue、LinkedBlockingDeque。
ArrayBlockingQueue:由数据支持的有界阻塞队列。
LinkedBlockingQueue:基于链接节点、范围任意的阻塞队列。
PriorityBlockingQueue:无界阻塞队列。
SynchronousQueue:一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作。
DelayQueue:Delayed元素的一个无界阻塞队列。
LinkedBlockingDeque:基于链接节点、范围任意的双端阻塞队列,可以在队列的两端添加、移除元素。
6、Lock
Lock分为公平锁和非公平锁,默认是非公平锁。实现类有ReetrantLock、ReetrantReadWriteLock,都依赖于AbstractQueuedSynchronizer抽象类。ReetrantLock将所有Lock接口的操作都委派到Sync类上,Sync有两个子类:NonFairSync和FaiSync,通过其命名就能知道分别处理非公平锁和公平锁的。AbstractQueuedSynchronizer把所有请求构成一个CLH队列,这里是一个虚拟队列,当有线程竞争锁时,该线程会首先尝试是否能获取锁,这种做法对于在队列中等待的线程来说是非公平的,如果有线程正在Running,那么通过循环的CAS操作将此线程增加到队尾,直至添加成功。
7、Atomic包
Atomic包下的类实现了原子操作,有对基本类型如int、long、boolean实现原子操作的类:AtomicInteger、AtomicLong、AtomicBoolean,如果需要对一个对象进行原子操作,也有对对象引用进行原子操作的AtomicReference类,还有对对象数组操作的原子类:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray。原子操作核心思想是CAS操作,然后调用底层操作系统指令来实现。
java多线程如何实现等待多个信号的功能
栅栏(CyclicBarrier)
import?java.util.concurrent.CyclicBarrier;
import?java.util.concurrent.ExecutorService;
import?java.util.concurrent.Executors;
public?class?CycTest
{
????
????public?static?void?main(String[]?args)
????{
????????ExecutorService?executorpool?=?Executors.newFixedThreadPool(3);
????????CyclicBarrier?cyclicBarrier?=?new?CyclicBarrier(3);
????????
????????CycWork?work1?=?new?CycWork(cyclicBarrier,?"张三");
????????CycWork?work2?=?new?CycWork(cyclicBarrier,?"李四");
????????CycWork?work3?=?new?CycWork(cyclicBarrier,?"王五");
????????
????????executorpool.execute(work1);
????????executorpool.execute(work2);
????????executorpool.execute(work3);
????????
????????executorpool.shutdown();
????????
????}
????
}
/**
?*?Runnable?线程类
?*/
class?CycWork?implements?Runnable
{
????
????private?CyclicBarrier?cyclicBarrier;
????
????private?String?name;
????
????public?CycWork(CyclicBarrier?cyclicBarrier,?String?name)
????{
????????this.name?=?name;
????????this.cyclicBarrier?=?cyclicBarrier;
????}
????
????@Override
????public?void?run()
????{
????????
????????System.out.println(name?+?"正在打桩,毕竟不轻松。。。。。");
????????
????????try
????????{
????????????Thread.sleep(5000);
????????????System.out.println(name?+?"不容易,终于把桩打完了。。。。");
????????????
????????????cyclicBarrier.await();
????????}
????????catch?(Exception?e)
????????{
????????????e.printStackTrace();
????????}
????????
????????System.out.println(name?+?":其他逗b把桩都打完了,又得忙活了。。。");
????????
????}
????
}
java并发countdownlatch和cyclicbarrier的区别
cyclibarriar 就是栅栏,顾名思义:就是一个拦截的装置。多个线程start后,在栅栏处阻塞住,一般定义栅栏的时候会定义有多少个线程。比如定义为4个,那么有三个线程到栅栏处,就阻塞住,如果没有第四个,就会一直阻塞,知道启动第四个线程到栅栏