[099]技术-jdk中的多线程相关的基本数据结构

2017-12-25  本文已影响0人  shawnxjf

CountdownLatch

countdownLatch为多个线程整体到达条件时通知await的线程,即时序图如下:


image.png

由图中我们知道,执行的.countDown()方法的线程不会阻塞会接着干自己的事情,当thread1,2,3这3个线程都已经执行了countdown的时候就会通知 countdownLatch.await()上等待的线程。 其具体表现是一拨人等另一拨人。

具体伪代码交互模式为:

main(){
  CountdownLatch countDownLatch = new CountDownLatch(5);  //主线程
  //countdown操作
  new Thread( new Runnable(){ public void run(){ countDownLatch .countdown() }}).start();
  new Thread( new Runnable(){ public void run(){ countDownLatch .countdown() }}).start();
 
 //await操作,等待countdownLatch变成0,才继续执行
  new Thread( new Runnable(){ public void run(){ countDownLatch .await() }}).start();
}

相关countlatchdown代码可以参考:https://blog.csdn.net/simonchi/article/details/47150173

CyclicBarrier

image.png

由图我们知道,所有调用了CyclicBarrier.await()的线程会被阻塞,知道所有在Cyclic上的线程都await了后会整体释放一起恢复执行。其具体表现是等一拨人筹齐了再走。

其交互伪代码为:

CyclicBarrier cb = new CyclicBarrier(3)
  new Thread( new Runnable(){ public void run(){ cb.await() }}).start();
  new Thread( new Runnable(){ public void run(){ cb.await()}}).start();
  //如果没有第三个线程执行cb.await()的话,那么 第一第二个线程永远在等待(除非被interrupted)

Exchanger

Exchange用于另个线程之间交换数据,如果一个线程thread1执行了Exchanger.exchange()方法另一个线程thread2还没有,那么thread1会被阻塞。其交互图如下:


image.png

Exchanger经常用于两个线程交换队列数据。

Final Exchanger<List<Integer>> exchanger = new Exchanger<List<Integer>>();
//两个线程交换队列
thread1 = new Thread
{
    new  Runnabler(){
       .......
        list1 =new Arraylist<String>();
        list1 = exchanger.exchanger(list1)
   }
}.start()

thread2 = new Thread
{
    new  Runnabler(){
       .......
        list2 =new Arraylist<String>();
        list2 = exchanger.exchanger(list2)
   }
}.start()

Semaphore

信号量用于控制线程之间的并发,比如5台机器8个工人操作每台机器只能被一个工人操作。那么可以通过semaphore来操作。

main(){
Semaphore semaphore = new Semaphore(5);
  new Runnable()
 {
   semaphore.acquire();//如果没有获取到线程阻塞
   .......do job....
  semaphore.release();
 }
}
//注意 semaphore.acquire()没有获取的话阻塞,如果不想阻塞可以替换成semaphore.tryacquire();//如果获取成功返回true,没有获取成功返回false

wait, notify,notifyAll

查看jdk Object.java 查看了释义,七对wait和notify解释如下:
wait:cause the current thread to wait until another thread to invoke the notify/notifyall method of this object.
1.首先什么是current thread即当前正在执行queue.wait()的线程 currentThread1。
2.我们需要通过另外一个线程 调用 queue.notify()来唤醒在 queue对象上等待的线程(有个等待队列)。

写代码需要注意以下几点:
1.wait和notify用于线程间协同,它是一个线程共享对象,所以需要加锁或者其他机制保证线程间可见和同步。
2.在调用wait的时候,要先判断是否条件不够。
具体以生产者消费者模型:

producer:
synchronized(queue)
{
   condition = hold
   queue.notifyall();
   
    // 唤醒等待的线程(consumer线程,告诉他们有工作可以做了)去取队列数据工作
}

consumer:
synchronized(queue)
{
 while (&lt;condition does not hold&gt;) //该consumer下次任务同样要判断
        queue.wait(timeout, nanos);
       // Perform action appropriate to condition  ->这个是被唤醒之后执行的吧。
     }
   }
}

疑问:要consumer线程一直while检查条件,那么意思是说queue.wati()后consumer线程还会去进行下一次循环遍历么?

上一篇下一篇

猜你喜欢

热点阅读