为什么需要通信?
当我们在多并发的环境下多个线程同时完成一个任务时,我们需要线程之间相互协调,如果没有一个合理的通信机制,那么线程之间相互争夺对象会造成很大的内耗,所以需要一个合理的通信机制。
怎么样实现?
可以根据不同的环境,有不同的机制实现。常见的机制分为两种类型,共享内存机制和消息传递机制。
等待唤醒机制
用于synchronized代码块中。属于共享内存机制
主要由两个方法构成wait()以及notify()。调用wait方法时会进入等待状态,调用notify方法时会唤醒线程。
调用wait方法后会释放锁,然后等待其他线程的通知。
调用notify方法后会唤醒一个等待当前对象锁的线程,即唤醒对象监视器上等待的单个线程,如果有多个线程在等待,唤醒的线程是随机选取的。
notify方法的使用方法应该为:锁所在的线程.notify()
此外还有notifyAll方法,可以唤醒所有线程。
与sleep相比不同之处在于sleep不释放锁。且sleep是Thread的方法,而wait、notify等是object方法。
局限性:只能唤醒同个对象监视器下的线程,即同个锁下。
Condition
condition的功能与等待唤醒机制功能类似,实现如下:(来源参考文献2)
Condition condition =lock.newCondition();
res. condition.await(); 类似wait
res. Condition. Signal() 类似notify
与Object的wait、notify不同之处在于作用的对象不同,Object是作用于synchronized,而Condition作用于Lock
sleep/yield/join
sleep,让线程睡眠一段时间,但不会释放锁。
yield,使线程从运行状态转化为就绪状态,由线程调度重新分配cpu。不释放锁
join,暂停当前线程,等待被调用线程执行结束后再继续执行。不释放锁,同时也不会启动调用的线程,所以需先确保线程已经start。
join底层实质为自旋等待。
CyclicBarrier栅栏
翻译为线程栅栏,当指定数量的线程执行到特定位置的时候,才触发后续动作。常用于保障所有线程同时开工。
管道通信机制
使用Java.io.PipedInputStream和Java.io.PipedOutputStream实现,属于消息传递机制。可以看我写的另一篇文章java io流汇总
本人小白学习记录用,欢迎留言互相交流学习。2018年12月28日13:37:24