学习思路:
- 线程同步-锁
- wait、notify
- join
- ThreadLocal
- 通过管道输入/输出流(字符流、字节流)
服务如果一直处于单线程访问,那将毫无意义,多用户访问必然产生多线程,而多线程访问必然离不开线程间通讯
一、线程同步-锁
多线程操作共享资源时势必会产生线程安全的问题(也就是我们说的线程相互影响),而遇到线程安全问题我们最先想到的基本都是锁,比如:syncrhoized、volatile、Lock等;但这些个锁都是基于单JVM来说是有效的,但就目前项目部署基本都是分布式集群部署,当然也就想到了分布式锁
题外话:volatile相关资料请看之前博客《多线程-线程安全-volatile》
二、wait、notify
wait、notify、nofifyAll都是Object的方法,调用过程:
- 线程A竞争拿到syncrhoized锁(锁对象X)后进入同步队列
- 在syncrhoized内部调用对象X的wait方法,线程A释放锁,从同步队列移到等待队列
- 线程B在syncrhoized内部调用X对象的notify/notifyAll方法,线程A从等待队列移除,重新进入同步队列,重新获取锁
注意:调用X.wait()之前X对象必须已经获得锁,调用notify/notifyAll的前提是对象必须已经获取到锁,换句话说:wait()/notify/notifyAll这三个方法必须在syncrhoized块内调用
三、join
线程A内调用了线程B的join方法(调用A的wait方法),那么线程A会等待线程B执行完后在继续往下执行(调用A的notifyAll方法)类似于A依赖于B的执行结果;跟上面的wait、notify不谋而合
四、ThreadLocal
顾名思义:线程跟本地变量绑定;为成员变量做一个本地备份(本地变量)跟线程绑定,在操作的时候只操作本地变量的值,线程间互不影响;如set方法可以设置一个值,get方法可以获取一个值
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
五、通过管道输入/输出流(字符流、字节流)
管道输入 / 输出流主要包括了如下四种具体实现:PipedOutputStream、PipedInputStream、PipedReader、PipedWriter,前两种面向字节,而后两种面向字符
这里的管道输入输出流跟文件的/网络的输入输出流不同之处是:它是线程间基于内存的数据传输
公众号主要记录各种源码、面试题、微服务技术栈,帮忙关注一波,非常感谢