Java多线程与并发库
从Java传统线程技术开始介绍,进而逐步介绍Java5之后的并发库API的原理和使用。
文章中包含:线程同步、互斥、同步技术,定时器技术,线程池、线程锁、条件阻塞、阻塞队列、各种同步工具的介绍。
文章中穿插多个面试题供读者进行练习。
光仔December
技术宅,系统集成项目管理工程师,FCP-报表开发工程师,全国软件开发(C/C++)专业人才高级认证,2014年ACM-ICPC河南省赛区银奖,2014年第五届蓝桥杯河南赛区C/C++程序设计本科B组二等奖,2015年甲骨文杯全国Java程序设计大赛华中赛区A组二等奖,2015年中国大学生计算机设计大赛团队三等奖
展开
-
【Java多线程与并发库】1.传统线程技术回顾
创建线程的两种传统方式(1)创建Thread的子类,重写run方法在Thread子类覆盖的run方法中编写运行代码。package cn.edu.hpu.test;public class ThreadTests { public static void main(String[] args) { new Thread(){ @Ove原创 2016-09-23 16:02:21 · 1600 阅读 · 0 评论 -
【Java多线程与并发库】2.传统定时器技术回顾
Java中的Timer类(java.util.Timer),是最常用的定时类,它可以在隔一段时间之后再去执行其run方法中设置的代码语句。使用Timer类定时执行程序有三种方法:(1)单次定时new Timer().schedule(task, time);给Timer类的schedule方法中传入一个TimerTask对象,并重写Task对象的run方法,将需要定时执原创 2016-09-23 16:07:38 · 1369 阅读 · 0 评论 -
【Java多线程与并发库】3.传统线程互斥技术
线程的同步互斥与通信互斥的问题在使用线程的时候是我们必须要注意的。例如两个线程同时开启,由于业务规则,需要访问同一个对象,要取得该对象中的数据进行修改。这样多个线程对同一个数据进行操作的实例有很多,例如银行交易。我们的账户中原来有2000元,在同一时间,我们刷卡200购物,然后有人给我们转账500元,我们的账户余额应该是2000-200+500=2300元。但是,在类似原创 2016-10-09 09:19:51 · 1332 阅读 · 0 评论 -
【Java多线程与并发库】5.线程范围内共享变量的概念与作用
我们可以使用ThreadLocal实现线程范围的共享变量。ThreadLocal的作用和目的,用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行又共享另外一份数据。线程范围内共享数据的示意图:每个线程调用全局ThreadLocal对象的set方法,对相当于往其内部的map中增加一条记录,key分别是各自原创 2016-10-11 12:58:03 · 2919 阅读 · 0 评论 -
【Java多线程与并发库】6.ThreadLocal类及应用技巧
之前我们了解了实现线程范围内数据共享的机制,接下来我们可以使用JDK5提供的ThreadLocal类,来实现线程范围内数据共享。ThreadLocal类其实就类似于我们上一次创建的Map。我们创建一个测试类,来使用ThreadLocal类实现线程范围内数据共享:我们的类A和类B每次都从线程中获取data值打印,为了保证每次打印的数据是该线程的数据,类A和类B的数据都从T原创 2016-10-12 09:52:16 · 1092 阅读 · 0 评论 -
【Java多线程与并发库】7.多个线程之间共享数据的方式探讨
多个线程访问共享对象和数据的方式1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有一个共享数据,例如售票系统就可以这么做这么做。2.如果每个线程执行的代码不同,这时候需要用不同的Runnable对象,有如下两种方式来实现这些Runnable对象之间的数据共享:(1)将数据封装在另外一个对象中,然后将这个对象逐一传递给各个Runn原创 2016-10-17 08:57:58 · 1159 阅读 · 0 评论 -
【Java多线程与并发库】8.java5线程并发库之线程池的应用
Java5中的线程的并发库并发库的代码均在Java的java.util.concurrent包下:并发库中最常用的,是“线程池”(1)线程池出现的原因什么是“线程池”呢?用“线程池”有什么好处呢?首先我们来举个例子。假设我们想写一个类似TomCat的服务器,其实是很难的,难点在于我们的性能升不上去。假设我们写好了这个伪TomCat,假设有一个原创 2016-10-19 11:39:36 · 1075 阅读 · 0 评论 -
【Java多线程与并发库】9.Callable与Future的应用
Callable&Future它们的作用是,我们启动一个线程,线程结束的时候会返回一个结果,我们可以通过Callable启动一个带返回数据的线程,通过Future获取线程返回的结果。例子:package cn.edu.hpu.test;import java.util.concurrent.Callable;import java.util.concurrent原创 2016-10-22 14:09:18 · 874 阅读 · 0 评论 -
【Java多线程与并发库】10.java5的线程锁(读写锁)技术
Lock&Condition实现线程同步通信(1)Lock概念Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。锁是加在代表要操作的资源的类的内部方法中,而不是线程代码中!例子:package cn.edu.hpu.test;pu原创 2016-10-23 15:46:45 · 1909 阅读 · 2 评论 -
【Java多线程与并发库】11.java5条件阻塞Condition的应用
Condition(1)概述Condition是Java有关锁的包下面的一个类,锁我们只能实现互斥,不能实现通知。而Condition就是解决这个问题,Condition的功能类似在传统线程技术中的Object.wait和Object.notify的功能。(2)实例记得我们之前写过的一个例子,一道面试题:子线程循环10次,接着主线程循环100次,接着又回到子线程循环10原创 2016-10-25 09:14:49 · 971 阅读 · 0 评论 -
【Java多线程与并发库】12.java5的Semaphere同步工具
Semaphore(信号灯)(1)概念Semaphore可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如实现一个文件允许的并发访问数。Semaphore实现的功能就类似于餐厅有5个座位,假如有10人要就餐,但同时只能有5个人能够坐下,当5个人的任何一个人让开后,其中在等待的另外5个人中又有一个人可以坐下了。原创 2016-10-27 18:12:21 · 905 阅读 · 0 评论 -
【Java多线程与并发库】13.java5的CyclicBarrier同步工具
CyclicBarrier循环路障(1)概念首先用通俗的话解释,表示大家彼此等待,大家集合好后才开始出发,分散活动后又在指定地点集合碰面,这就好比整个公司的人员利用周末时间集体郊游一样,先各自从家出发到公司集合后,再同时出发到公园游玩,然后在指定地点集合后再同时开始就餐的场景。CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (co原创 2016-10-31 11:19:35 · 912 阅读 · 0 评论 -
【Java多线程与并发库】14.java5的CountDownLatch同步工具
CountDownLatch犹如倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当计数器到达0时,则所有等待着或单个等待着开始执行。可以实现一个人(也可以是多个人)等待其它所有人来通知他,也可以实现一个人通知多个人的效果,类似裁判一声口令,运动员同时开始奔跑,或者所有运动员都跑到终点后裁判才可以公布结果,这个功能适合做类似百米赛跑的原创 2016-11-02 09:06:29 · 803 阅读 · 0 评论 -
【Java多线程与并发库】15.java5的Exchanger同步工具
Exchanger用于实现两个人之间的数据交换,每个人在完成一定的事务后想与对方交换数据,第一个先拿出数据的人将一直等待第二个人拿着数据到来时,才能彼此交换数据。比喻:好比两个毒贩要进行交易,一手交钱,一手交货,不管谁先来到接头地点,都要处于等待状态,当另一方也到达了接头地点(所谓到达接头地点,也就到达了准备接头的状态)时,两者的数据立即交换了,然后又可以各忙各的了。原创 2016-11-03 14:03:47 · 825 阅读 · 0 评论 -
【Java多线程与并发库】16.java5阻塞队列的应用
可阻塞的队列阻塞队列就是Java5的并发库给我们提供的一个集合。(1)队列队列是一个数组或集合,遵循数据“先入先出”的原则。阻塞队列就是当队列满员的时候,新加入的队列成员要等待队列的满员状态解除(即有元素出队)才能插入队列。非阻塞队列当队列满员的时候有新的元素插入,此时程序会报错。队列包含固定长度的队列和不固定长度的队列。我们自己来设计一个阻原创 2016-11-06 10:01:15 · 957 阅读 · 0 评论 -
【Java多线程与并发库】17.java5同步集合类的应用
同步集合(1)传统集合的缺陷传统的集合,在并发访问的时候,是有问题的。如hashset、hashmap和arrayList,多个线程在对他们取数据、放数据的时候,是有问题的,因为他们是线程不安全的。由于没有控制并发,会导致数据的不一致,引起死循环。为什么会引起死循环?拿HashMap来看,看一下HashMap的get函数的源代码:public V get(Obj原创 2016-11-07 09:41:35 · 1262 阅读 · 5 评论 -
【Java多线程与并发库】18.java线程面试题1
现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印玩这些日志对象。原始代码如下:package cn.edu.hpu.test;public class ReadTest { public static void main(String[]原创 2016-11-10 15:23:06 · 2259 阅读 · 0 评论 -
【Java多线程与并发库】19.java线程面试题2
现有的Test类中代码在不断的产生数据,然后交给TestDo.doSome()方法去处理,就好像生产者在不断地产生数据,消费者在不断消费数据。请将程序改造成有10个线程来消费生成者产生的数据,这些消费者都调用TestDo.doSome()方法去进行处理,故每个消费者都需要一秒才能处理完,程序应该保证这些消费者线程依次有序地消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据原创 2016-11-11 09:54:06 · 1167 阅读 · 0 评论 -
【Java多线程与并发库】20.java线程面试题3
题目描述:现有程序同时启动了4个线程去调用TestDo.doSome(key,value)方法,由于TestDo.doSome(key,value)方法内的代码是先暂停1秒,然后再输出以秒为单位的当前时间值,所以,会打印出4个相同的时间值,如下所示:4:4:12584448921:1:12584448923:3:12584448921:2:1258444892请修改原创 2016-11-12 18:46:22 · 1502 阅读 · 0 评论