欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java 同步器SynchronousQueue详解及实例

程序员文章站 2024-02-22 10:22:28
同步器简介        学习以来对线程的操作有很大的改观,从c/c++的mutex到java的各种锁(当然不...

同步器简介

       学习以来对线程的操作有很大的改观,从c/c++的mutex到java的各种锁(当然不是嫌麻烦,java读写锁的实现还是带来不少好处的,但是sokcet的设计我就不敢恭维了,tcp和udp是两个类,弄得我现在对udp也不怎么熟悉)。其中最让我感到特别刚需的设计就是同步器,除了countdownlatch,剩下的都比较刚需,cyclicbarrier我现在唯一能感觉他的好用处就是循环打印a,b,exchanger和synchronousqueue我一直没发现什么作用,两个就适合生产者消费者问题。以上就是四大同步器,听说过2个以上的就很厉害了,有些场合太难想了。

场景思路

      这次说最后两个用的场景吧,我要做的事情呢,是采集一堆数据,然后采集另外的数据综合处理,但是两个数据是和时间相关的,如果顺序执行的话,那么处理结果的可信度越低,最初的设想就是利用异步处理,两个数据采集同时进行,然后一起处理,futuretask,就作为首选,我的采集信息还是周期性的任务,必需要用定时的线程池了,但是这种线程池(别说timer,这个类更建议用线程池替换)并没有为异步处理做返回值,我也没办法直接获取处理的数据了,无奈的情况下只能用线程来做了,同时也必须要用同步器来同步了,用手动阻塞线程然后唤醒这个行为实在是太不可取了,你全唤醒了,可能造成不该运行的代码开始运行,唤醒单个,还得看cpu的调度,于是想到了exchanger和synchronousqueue,我最终选取了synchronousqueue。

synchronousqueue

        其实就是特殊的阻塞队列,特殊就特殊在他最多放一个元素,而且这个元素不在特定的时间消费掉就没了,而且永远长度都是0,具体看api就发现能用的方法没几个,3个是放入,2个是取走。

demo

生产者,消息最多存放1分钟

public void run() {
  try {
  queue.offer(i++,1,timeunit.minutes);
  } catch (interruptedexception e) {
  e.printstacktrace();
  }
  system.out.println("add");

 }

消费者

system.out.println(queue.poll(1,timeunit.seconds));

用了这个同步器,这种定时生产者消费者问题,代码量就很少,不需要自己再写同步的代码了。也避免了最初唤醒阻塞带来的不可预估性。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!