请问 java并发包中的 Thread exclusiveOwnerThread 为什么用 transient 修饰?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请问 java并发包中的 Thread exclusiveOwnerThread 为什么用 transient 修饰?相关的知识,希望对你有一定的参考价值。
并发抽象类 AbstractOwnableSynchronizer 中的当前线程的拥有者为啥要用 transient 关键字修饰?
参考技术A FixedThreadPool模式会使用一个优先固定数目的线程来处理若干数目的任务。规定数目的线程处理所有任务,一旦有线程处理完了任务就会被用来处理新的任务(如果有的话)。这种模式与上面的CachedThreadPool是不同的,CachedThreadPool模式下处理一定数量的任务的线程数目是不确定的。而FixedThreadPool模式下最多的线程数目是一定的。采用FixedThreadPool模式编写客户端程序如下:packagenet.jerryblog.concurrent;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;publicclassFixedThreadPoolpublicstaticvoidmain(String[]args)//三个线程来执行五个任务ExecutorServiceexec=Executors.newFixedThreadPool(3);for(inti=0;i<5;i++)exec.execute(newLiftOff());exec.shutdown();3.SingleThreadExecutor模式SingleThreadExecutor模式只会创建一个线程。它和FixedThreadPool比较类似,不过线程数是一个。如果多个任务被提交给SingleThreadExecutor的话,那么这些任务会被保存在一个队列中,并且会按照任务提交的顺序,一个先执行完成再执行另外一个线程。SingleThreadExecutor模式可以保证只有一个任务会被执行。这种特点可以被用来处理共享资源的问题而不需要考虑同步的问题。SingleThreadExecutor模式编写的客户端程序如下:packagenet.jerryblog.concurrent;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;publicclassSingleThreadExecutorpublicstaticvoidmain(String[]args)ExecutorServiceexec=Executors.newSingleThreadExecutor();for(inti=0;i<2;i++)exec.execute(newLiftOff());这种模式下执行的结果如下:#0(9)#0(8)#0(7)#0(6)#0(5)#0(4)#0(3)#0(2)#0(1)#0(LiftOff!)第一个任务执行完了之后才开始执行第二个任务。Java并发包中的并发队列简记
ConcurrentLinkedQueue
ConcurrentLinkedQueue内部的队列使用带头节点的单向链表实现,并且维持头尾两个指针,头指针出队、尾指针入队。该队列的出队入队操作都是线程安全的。
保证安全的方式
对于头尾指针均使用volatile关键字修饰从而保证可见性,对于头尾指针的修改使用CAS操作保证了原子性。所以对于出入队是线程安全的。
主要方法
offer:入队操作
add:添加元素,内部通过调用offer实现
poll:出队操作,删除队头元素并返回
peek:获取对头元素,不删除结点
size:返回队列的大小,由于队列没有加锁,返回结果可能不准确,在返回时队列有可能被其它线程修改
remove:删除队列中指定的元素,有多个满足的元素时删除第一个
contains:判断是否包含某个元素,和size一样的原因,导致结果也可能不准确
LinkedBlockingQueue
LinkedBlockingQueue同样使用单向链表,并且维持头尾两个指针,另外使用了一个原子变量count来记录当前队列的结点数量。
保证线程安全的方式
对于出队和入队分别设置了takeLock和putLock两个独占锁,保证同一时刻只有一个线程可以进行出队或者入队操作,另外使用notEmpty和notFull两个条件变量用于存由于放入队和出队阻塞的线程。
主要方法
offer:非阻塞的入队操作,如果没有空间,则直接丢弃入队的元素返回false
put:阻塞的入队操作,如果没有空间,就把当前线程放入notFull的条件队列中,并且在获取锁时可相应中断
poll:非阻塞的出队操作,如果队列为空则直接返回false
peek:获取对头元素,不删除队头,该操作也是非阻塞的
take:阻塞的出队操作,如果队列为空,则线程被放入notEmpty条件队列中,并且在获取锁时可相应中断
remove:删除队列指定的元素
size:获取队列的大小,通过count原子变量获取,由于出对入队均加锁,所以结果是准确的
ArrayBlockingQueue
ArrayBlockingQueue与LinkedBlockingQueue的具体操作基本一致,不同点在于ArrayBlockingQueue底层是使用数组实现的循环队列,另外关于加锁方面ArrayBlockingQueue对出队和入队使用的是同一个锁,锁的粒度比LinkedBlockingQueue大,在获取size时ArrayBlockingQueue需要加锁获取,因为count使用的是普通变量。
以上是关于请问 java并发包中的 Thread exclusiveOwnerThread 为什么用 transient 修饰?的主要内容,如果未能解决你的问题,请参考以下文章