reentrantlock

java面试题

混江龙づ霸主 提交于 2019-12-16 13:12:43
1、多线程有什么用? 一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了,还管它有什么用?在我看来,这个回答更扯淡。所谓"知其然知其所以然","会用"只是"知其然","为什么用"才是"知其所以然",只有达到"知其然知其所以然"的程度才可以说是把一个知识点运用自如。OK,下面说说我对这个问题的看法: 1)发挥多核CPU的优势 随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4核、8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。单核CPU上所谓的"多线程"那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行罢了。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。 2)防止阻塞 从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题

ReentrantLock.lock() doesn't block other threads

时光毁灭记忆、已成空白 提交于 2019-12-14 03:47:04
问题 I'm having a hard time understanding the behavior of ReentrantLock.lock() I have the following class import java.util.concurrent.locks.*; class BlockingClass { private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void a() { lock.lock(); System.out.println("called in method a(): lock()"); try { System.out.println("called in method a(): await()"); condition.await(); } catch (InterruptedException e) {} finally { lock.unlock(); System.out.println(

ReenTrantLock

邮差的信 提交于 2019-12-13 22:37:27
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> ReentrantLock的核心是AQS,那么它怎么来实现的,继承吗?说说其类内部结构关系。 ReenTrantLock是实现Lock接口,内部有三个内部类 Sync ,NonFairSync ,FairSync ,后两个继承自Sync,而Sync继承自AQS ,NoFairSync是用来实现非公平锁,FireSync用来实现公平锁 ReentrantLock是如何实现公平锁以及非公平锁的? 公平锁是使用FairSync了,是直接使用aqs的acquire方法就好了,CLH队列为FIFO所以可以直接保证,具体可以看AQS实现。 非公平锁是使用NonFairSync.lock(),如果可以发现资源是空闲状态就直接占,不是空闲就尝试获取。 ReentrantLock默认实现的是公平还是非公平锁? 默认是非公平锁,实例化的时候传true时为公平锁(new ReenTrantLock(true)) 来源: oschina 链接: https://my.oschina.net/u/4291478/blog/3142850

J.U.C剖析与解读2(AQS的由来)

人走茶凉 提交于 2019-12-12 13:51:51
J.U.C剖析与解读2(AQS的由来) 前言 前面已经通过实现自定义ReentrantLock与自定义ReentrantReadWriteLock,展示了JDK是如何实现独占锁与共享锁的。 那么实际JDK源码中的ReentrantLock与ReentrantReadWritreLock是如何实现的呢?我们现有的自定义代码是否可以更进一步呢? 答案是肯定的。注意看我之前两个Lock的朋友,应该注意到了。自定义ReentrantReadWriteLock的独占锁部分,其实和自定义ReentrantLock是几乎一样的。 也就是说,不同Lock其实现是差不多的。那么是否可以提取公共的部分,是否可以写得更加优雅一些。 那么这篇博客,就是通过提取公共代码,引入模板方法设计模式,并利用Java的一些特性,写出一个自定义的AQS。 当然,最后也会剖析源码中AQS实现与我们自定义AQS的差别所在,并解读源码AQS中一些高级应用,如AQS通过一个state实现读写锁的持有数量(居然通过一个int值的CAS操作,解决了自定义读写锁持有数量的独占操作)。 如果看过源码的朋友,会发现源码中的ReentrantLock会自定义一个Sync,该Sync会继承一个AbstratQueueSynchronizer(简称AQS)。然后源码中的ReentrantLock的tryLock等方法

19.2 线程同步和安全问题

流过昼夜 提交于 2019-12-11 19:06:38
买票案例: 需求:某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票 步骤: 定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private int tickets = 100; 在SellTicket类中重写run()方法实现卖票,代码步骤如下 判断票数大于0,就卖票,并告知是哪个窗口卖的 卖了票之后,总票数要减1 票没有了,也可能有人来问,所以这里用死循环让卖票的动作一直执行 定义一个测试类SellTicketDemo,里面有main方法,代码步骤如下 创建SellTicket类的对象 创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称 启动线程 实现代码: public class SellTicket implements Runnable { private int ticketsNum = 100; @Override public void run() { sellTicket(); } private void sellTicket() { while (true) { if (ticketsNum > 0) { try { //实际生活中 买票会有延迟 Thread.sleep(100); } catch

AbstractQueuedSynchronizer

冷暖自知 提交于 2019-12-11 03:38:49
AQS, 即AbstractQueuedSynchronizer,一个基于FIFO的队列同步器,是实现lock的基础,AQS是一个抽象类,继承了AbstractOwnableSynchronizer抽象类,其总体结构如下: 包含内部类Node ,ConditionObject。 AQS的结构 AQS是一个基于双向链表的队列,类中定义了三个变量head, tail, state 分别代表队列的头结点,尾节点,对应锁状态(是否被占用、被重用),当一个线程获取同步锁失败时,会将该线程信息封装成一个Node对象存放在AQS队列的尾部,并阻塞该线程,当同步状态释放时,会去唤醒队列的头结点。 Node类 : 关于node类,保存的是获取同步锁失败的线程信息,其中最关键的是四种(五种)状态: Cancelled : 取消状态,值为1,表示当前线程状态为取消状态,线程被标记为取消状态后,后续操作会将该node节点从队列中删除。 Signal : 唤醒状态, 值为-1, 表示当前线程状态为唤醒状态,线程被标记为唤醒状态后,后续操作会让node节点对应线程会去尝试获取同步锁。 Condition: condition(条件)状态,值为-2, 表示当前线程等待一个Condition条件唤醒 Propagate:(没看明白) 初始状态:值为0 ConditionObject类: 稍后补充 AQS源码

Is a DelayQueue without fairness problematic?

删除回忆录丶 提交于 2019-12-11 02:16:36
问题 In Java 7 the implementation of DelayQueue uses a ReentrantLock without a fairness policy. Is this a problem in the long run? Can a thread starve because of this? Thanks 回答1: If you consider the ScheduledThreadPoolExecutor (or any other producer/consumer situation), the worker threads are independent and so should be the jobs in the DelayQueue . So, no: the order in which threads are allowed to take/poll does not make a difference. 来源: https://stackoverflow.com/questions/15604295/is-a

How will ReentrantLock object created inside a method's local scope work?

半腔热情 提交于 2019-12-11 01:51:58
问题 The above is a screen print from OCP 7 java se book. page 791. My question is if a new ReentrantLock object is created in a method every time and locked, how would that stop two threads from running the code block in between lock and unlock ? Won't the two threads create a ReentrantLock object each and lock it? I can imagine how this would work if lock object was a instance variable only instantiated once and never changed. (preferrably final ). Am I misunderstanding something? I had already

LinkedBlockingQueue与ArrayBlockingQueue

北城余情 提交于 2019-12-10 18:38:49
阻塞队列与普通的队列(LinkedList/ArrayList)相比,支持在向队列中添加元素时,队列的长度已满阻塞当前添加线程,直到队列未满或者等待超时;从队列中获取元素时,队列中元素为空 ,会将获取元素的线程阻塞,直到队列中存在元素 或者等待超时。 在JUC包中常用的阻塞队列包含ArrayBlockingQueue/LinkedBlockingQueue/LinkedBlockingDeque等,从结构来看都继承了AbstractQueue实现了BlockingQueue接口(LinkedBlockingDeque是双向阻塞队列,实现的是BlockingDeque接口),在BlockingQueue接口中定义了几个供子类实现的接口,可以分为3部分,puts操作、takes操作、其他操作。 puts操作 add(E e) : 添加成功返回true,失败抛IllegalStateException异常 offer(E e) : 成功返回 true,如果此队列已满,则返回 false(如果添加了时间参数,且队列已满也会阻塞) put(E e) :将元素插入此队列的尾部,如果该队列已满,则一直阻塞 takes操作 remove(Object o) :移除指定元素,成功返回true,失败返回false poll() : 获取并移除此队列的头元素,若队列为空,则返回 null

BlockingQueue

故事扮演 提交于 2019-12-10 18:33:45
1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。 阻塞队列提供了四种处理方法: 方法\处理方式 抛出异常 返回特殊值 一直阻塞 超时退出 插入方法 add(e) offer(e) put(e) offer(e,time,unit) 移除方法 remove() poll() take() poll(time,unit) 检查方法 element() peek() 不可用 不可用 异常:是指当阻塞队列满时候,再往队列里插入元素,会抛出IllegalStateException("Queue full")异常。当队列为空时,从队列里获取元素时会抛出NoSuchElementException异常 。 返回特殊值:插入方法会返回是否成功,成功则返回true。移除方法,则是从队列里拿出一个元素,如果没有则返回null 一直阻塞:当阻塞队列满时,如果生产者线程往队列里put元素,队列会一直阻塞生产者线程,直到拿到数据,或者响应中断退出。当队列空时,消费者线程试图从队列里take元素