并发调试、工具、容器!
参考文献:
volatile 关键字
-
volatile 关键字的作用(变量可见性、禁止重排序),不能保证原子性
-
使用场景
- 通常修饰状态(boolean和int)
- 单纯的赋值
同步机制
-
监视器锁(synchronized)
悲观锁
-
显示锁(ReentrantLock、ReadWriteLock)
还提供了诸如可响应中断锁、可轮询锁请求、定时锁等避免多线程死锁的方法
-
原子变量(AtomicInteger、AtomicLong、AtomicBoolean)
乐观锁、CAS(比较提换)
-
volatile
-
线程封闭(模拟单线程,规避多线程环境)
不共享数据
- 栈封闭
- ThreadLocal
发令枪
CountDownLatch(线程计数器 )
static CountDownLatch cdl = new CountDownLatch(20);
...
cdl.countDown(); // 此处要调用20次
...
cdl.await(); // 阻塞,countDown计数20次后才统一走下一步程序
// 类似发令枪,统一起跑
Tomcat7 和 Tomcat8 的默认IO模型区别
tomcat7默认使用BIO,一个请求对应一个线程,阻塞
tomcat8默认使用NIO,一个线程可处理多个请求,非阻塞
-
启动NIO模式
修改tomcat7为NIO
<Connector port="8080"protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443"/>
-
线程池
默认的tomcat没有启用线程池,在tomcat中每一个用户请求都是一个线程,所以可以使用线程池提高性能。这里前台其实有一个调度线程,然后调度线程会放入线程池内,然后到到一定的时候线程池的任务变成工作线程
放开配置文件的下面注释,并在Connector中指定执行器
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/> <!-- executor="tomcatThreadPool"为上面的执行器 --> <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
spring 单例支持多线程并发
为什么局部变量不会受多线程影响?
-
对于那些会以多线程运行的单例类,例如Web应用中的Servlet,每个方法中对局部变量的操作都是在线程自己独立的内存区域内完成的,所以是线程安全的
-
局部变量不会受多线程影响
-
成员变量会受到多线程影响
-
对于成员变量的操作,可以使用ThreadLocal来保证线程安全
在bean对象中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中