作为业务开发人员,能够在工作中用到的技术其实不多。虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上。因为,我们用的框架已经把这些事做掉了。
比如web开发,外面有大量的请求进来,按理说,我们应该考虑并发问题。但其实,spring接到请求,分配到controller之后,就已经是线程安全的了,所以我们要做的就是,从controller开始,到最后请求响应结束,保证线程安全即可。
多线程好像有很多东西需要注意,阅读《Java 多线程编程核心技术》后,做个总结,总体来说,其实也没那么多事,没那么复杂。
1. 多线程基础
java的多线程,就体现在Thread类与Runable接口!共享数据,才存在线程安全问题,不共享数据不存在线程安全。java的很多停止线程的方法已经废除,不建议使用如: resume,stop,suspend方法。设置线程优先级(setPriority)可能提高线程执行的速度。守护线程的存在需要至少一个非守护线程在运行,也就是说守护线程不能独立存在,其能力是比较低的,比如GC就是守护线程,当你的代码在执行时,GC就在运行,随时进行内存回收,当你的程序执行完成后,GC线程就不存在了。
2. 对象及变量的并发访问
synchronized同步方法,锁对象,锁代码块,锁方法,锁变量,
valatile关键字,使用volatile线程解决同步死循环不停止问题。volatile强制从公共堆中获得变量的值,使保持一致性。
3. 线程间通信
wait/notify 是最基本的实现线程间通信的方式。很方便的实现了,消费者/生产者模式。
wait方法后,立即释放锁,notify锁不释放。即wait方法执行后,后续并发请求即可进入该块,而notify则需要等到synchronized代码块执行完成后,才会释放锁。
notifyAll()唤醒所有等待线程。
join()方法释放锁等待线程执行完成。Thread.sleep()不释放锁等待。
通过管道进行通信,以字符流形式传递。PipeWriter,PipeReader,outputSream.connect(inputStream)将输入流与输出联系在 一起。
ThreadLocal,可认为是一个线程级的全局变量,即在本线程中,随处都可以取到该值,而不必担心线程安全问题。set(),get()方法进行设置与取用。
4. Lock的使用
ReentrantLock,
5. 定时器timer
timer.schedule(task, dateRef) 执行一次, timer.schedule(task, dateRef, period) 周期性执行。
6. 单例模式与多线程
if(obj == null) { synchronized(MyObject.class) { if(obj == null) { obj = new MyObject(); } } }
额,这么看来,多线程的知识还是好少呢。东西不要太多,够精就行!
不用害怕多线程,不用害怕并发!