JAVA并发我爱编程程序员

java多线程高级教程,这些你都懂了吗?

2018-04-08  本文已影响117人  程序员日常填坑

一、countdownLatch和cyclicbarrier(这两个做多线程控制很好用,工作中会经常用到)

countdownLatch:主线程阻塞,当多个线程countdown到0,主线程执行;

cyclicbarrier:多个线程等待,当都处于等待状态了一起执行(类似于赛跑机制)

countdownLatch

cyclicbarrier

二、volatile和threadlocal

这两个也要很好掌握,不仅常用,而且面试时候也经常问到!

volatile:使属性可见性。有个属性是共享属性,这个关键字会在每个线程内开一块内存,每次子线程都会从主线程拿最新的属性放到内存中。但是有个问题,他只是拿最新的,比如:计数器,每个线程都执行+1操作。一个线程+1,另外两个同时读取这个属性,那么不会加2次,而是只加一次,这就是valatile不能保证原子性的原因。

threadlocal:用于做方法外的全局属性。这个跟volatile刚好相反,使全局变量独立,每个线程里都有一份独立副本。

这是hibernate的源码,如果当前线程没有session就openSession放到ThreadLocalMap中,每个线程的session都是独立的不会相互受影响。

三、AtomicInteger:支持原子性计数器。

之前说volatile不能作为计数器,那么多线程计数器要用atomic类的AtomicInteger

四、并发类容器

ConCurrentHashMap、CopyAndWriteArrayList、CopyAndWriteArraySet。

ConCurrentHashMap(底层分成16个hashtable来保证并发)读支持高并发读,写和删除时候只支持16个线程,所以一般也要上锁; copyandwrite支持高并发读,写的话要加锁(原理是,写的时候赋值一个容器,写好了把指针指向新容器并且删除原容器)

map、list、set都有并发类容器。面试时候经常会问hashmap和ConCurrentHashMap区别。这个demo我就不写了,用法和我们平时用的集合都一样,只是他们不会造成线程不安全。

五、并发类队列

阻塞的意思是,当达到队列最大容量或者为空,线程还往里加东西或取东西会被阻塞;有界意思,可以设置队列大小。

(非阻塞队列)ConcurrentLinkedQueue无阻塞无界限队列(高并发性能最好,peek取出不删除,poll取出删除),

(阻塞队列)ArrayBlockingQueue阻塞有界队列,LinkBlockingQueue阻塞无界队列(生产者消费者首选,take方法会阻塞,poll方法没有就返回null)。

这里我们以最经典的生产者消费者模式作为例子

这里我们顺便做一个延伸,我们用的所有线程池,包括面试时候经常问的要你自定义一个线程池怎么做?我们先看一下线程池的源码。

也就是说线程池也是用并发队列作为线程的容器。我们自定义时候也只需要重现实例化ThreadPoolExcutor,设置我们自己需要的参数即可。

六、分布式锁

这个其实已经不属于java代码范畴,但是我上一篇讲基础的时候,一些兄弟说我说的太简单,另一些又说太难,所以我加了一个分布式锁,希望能满足更多人需求。

分布式锁,主要用在分布式集群上,既然是分布式,那就有多个jvm,即使你代码写出花来也不能控制。所以只有一个办法就是借助第三方工具。比如memcache、redis、zk

1. 首先明确一点,有人可能会问是否可以考虑采用ReentrantLock来实现,但是实际上去实现的时候是有问题的,ReentrantLock的lock和unlock要求必须是在同一线程进行,而分布式应用中,lock和unlock是两次不相关的请求,因此肯定不是同一线程,因此导致无法使用ReentrantLock。

2. 基于数据库表做乐观锁,用于分布式锁。

3. 使用memcached的add()方法,用于分布式锁。

4. 使用memcached的cas()方法,用于分布式锁。(不常用)

5. 使用redis的setnx()、expire()方法,用于分布式锁。

6. 使用redis的setnx()、get()、getset()方法,用于分布式锁。(本人最常用的也是唯一用的方法)

7. 使用redis的watch、multi、exec命令,用于分布式锁。(不常用)

8. 使用zookeeper,用于分布式锁。(不常用)

这个我就不举demo了,不然太多了

技术大牛亲讲,7个月后,进入名企拿高薪。内容有:Java工程化、高性能及分布式、高性能、深入浅出。高架构。性能调优、Spring,MyBatis,Netty源码分析和大数据等多个知识点。如果你想拿高薪的,想学习的,想就业前景好的,想跟别人竞争能取得优势的,担心面试不过的,你都可以来,q群号为:230419550

注:加群要求

1、具有1-5工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的可以加。

2、在公司待久了,过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加。

3、如果没有工作经验,但基础非常扎实,对java工作机制,常用设计思想,常用java开发框架掌握熟练的,可以加。

4、觉得自己很牛B,一般需求都能搞定。但是所学的知识点没有系统化,很难在技术领域继续突破的可以加。

5.阿里Java高级大牛直播讲解知识点,分享知识,多年工作经验的梳理和总结,带着大家全面、科学地建立自己的技术体系和技术认知!

上一篇下一篇

猜你喜欢

热点阅读