java基础加强6--线程并发库

ThreadLocal实现线程范围的共享变量:

    ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据。

每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map中增加一条记录,key分别是各自的线程,value是各自的set方法传进去的值,在线程结束时要记住调用ThreadLocal.clear()方法。

ThreadLocal的应用场景:

订单处理包含一系列操作:减少库存量、增加一条流水台帐、修改总账,这几个操作要在同一个事务中完成,通常也即同一个线程中进行处理,如果累加公司应收款的操作失败了,则应该把前面的操作回滚,否则,提交所有操作,这要求这些操作使用相同的数据库连接对象,而这些操作的代码分别位于不同的模块类中。

银行转账包含一系列操作:把转出账户的余额减少,把转入账户的余额增加,这两个操作要在同一个事务中完成,它们必须使用相同的数据库连接对象,转入和转出操作的代码分别是两个不同的帐户对象的方法。

例如Strut2ActionContext,同一段代码被不同的线程调用运行时,该代码操作的数据是每个线程各自的状态和数据,对于不同的线程来说,getContext方法拿到的对象都不相同,对同一个线程来说,不管调用getContext方法多少次和在哪个模块中getContext方法,拿到的都是同一个。

Java5中的线程并发库:

线程池的概念与Executors类的应用:

   创建固定大小的线程池

   创建缓存线程池

   创建单一线程池

关闭线程池:

   shutdownshutdownNow

Callable&Future

   Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的。

   Callable要采用ExecutorServicesubmit方法提交,返回的future对象可以取消任务。

   CompletionService用于提交一组Callable任务,其take方法返回已完成的一个Callable任务对应的Future对象。

Lock&Condition实现线程同步通信:

两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。

读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁。

在等待Condition时,允许发生“虚假唤醒”,这通常作为对基础平台语义的让步。对于大多数应用程序,这带来的实际影响很小,因为Conditon应该总是在一个循环中被等待,并测试正被等待的状态声明。某个实现可以随意移除可能的虚假唤醒,但建议应用程序员总是假定这些虚假唤醒可能发生,因此总是在一个循环中等待。

一个锁内部可以有多个Condition,即有多路等待和通知,在传统的线程机制中一个监视器对象上只能有一路等待和通知,要想实现多路等待和通知,必须嵌套使用多个同步监视器对象。(如果只用一个Condition,两个放的都在等,一旦一个放的进去了,那么它通知可能会导致另一个放接着往下走。)

Semaphore实现信号灯:

Semaphore可以轻松完成信号量控制,即控制同时访问的线程个数,例如,实现一个文件允许的并发访问数。

Semaphore可以维护当前访问自身的线程个数,并提供了同步机制。

与阻塞队列有些相似,但也不同,阻塞队列是一方存放数据,另一方释放数据,Semaphore通常则是同一方设置和释放信号量。

其他同步工具类:

CyclicBarrier: 

表示大家彼此等待,大家集合好后才开始出发,分散活动后又在指定地点集合碰面。

CountDownLatch

表示一个人(也可以是多个人)等待其他所有人都来通知他,这犹如一个计划需要多个领导都签字后才能继续向下实施。还可以实现一个人通知多个人的效果,类似裁判一声口令,运动员同时开始奔跑。

Exchanger

用于实现两个人之间的数据交换,每个人在完成一定的事务后想与对方交换数据,第一个先拿出数据的人将一直等待第二个人拿着数据到来时,才能彼此交换数据。

可阻塞的队列:

ArrayBlockingQueue:只有put方法和take方法才具有阻塞功能。

同步集合类:

ConcurrentHashMap

CopyOnWriteArrayList

CopyOnWriteArraySet

你可能感兴趣的:(java学习整理)