这篇文章是研一刚入学时写的,今天整理草稿时才被我挖出来。当时混混沌沌的面试,记下来了一些并发的面试问题,不少尚未回答。到如今也学习了很多并发的知识,回过头来看这些问题和当时整理的答案,漏洞百出又十分好笑。发表出来权当对本身的一个提醒——若是不能一直进步,你就看不到当初傻逼的本身。 java
曾经,我在面试Java研发实习生时最常听到的一句话就是:git
搞Java怎么能不学并发呢?程序员
没错,真的是通过了面试官的无数鄙视,我才知道Java并发编程在Java语言中的重要性。github
悲观锁假设最坏的状况(若是你不锁门,那么捣蛋鬼就会闯入并搞得一团糟),而且只有在确保其余线程不会干扰(经过获取正确的锁)的状况下才能执行下去。面试
常见实现如独占锁等。算法
安全性更高,但在中低并发程度下的效率更低。编程
乐观锁借助冲突检查机制来判断在更新过程当中是否存在其余线程的干扰,若是存在,这个操做将失败,而且能够重试(也能够不重试)。安全
常见实现如CAS等。并发
部分乐观锁削弱了一致性,但中低并发程度下的效率大大提升。函数
从面相接口的角度上讲,实际上只有一种方法实现Runable接口;但Thread类为线程操做提供了更多的支持,因此一般作法是实现Runable接口,实例化并传入Thread类的构造函数。
经过synchronized关键字修饰每一个方法。
依据synchronized关键字引伸出如下问题。
持有锁的对象不一样:
从而致使两者的意义不一样:
ConcurrentHashMap的线程安全实现与HashTable不一样:
要从最简单的答起,业界最经常使用的是重点,有新意就放在最后。
List list = Collection.synchronizedList(new ArrayList())
。从而引伸出以下问题:
Exchanger、Callable&Future、阻塞队列BlockingQueue的实现原理
算法核心可归纳为两步:
详细待补充。
参考:
最大的不一样是在等待时wait会释放锁,而sleep一直持有锁。Wait一般被用于线程间交互,sleep一般被用于暂停执行。
主要缘由是JAVA提供的锁是对象级的而不是线程级的,每一个对象都有锁,经过线程得到。因为wait,notify和notifyAll都是锁级别的操做,因此把他们定义在Object类中由于锁属于对象。
Java API强制要求这样作,若是你不这么作,你的代码会抛出IllegalMonitorStateException异常。还有一个缘由是为了不wait和notify之间产生竞态条件。
处于等待状态的线程可能会收到错误警报和伪唤醒,若是不在循环中检查等待条件,程序就会在没有知足结束条件的状况下退出。
两个方法均可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中, 而submit()方法能够返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩展了Executor接口,其它线程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法。
Volatile变量能够确保先行关系,即写操做会发生在后续的读操做以前, 但它并不能保证原子性。例如用volatile修饰count变量那么 count++ 操做就不是原子性的。而AtomicInteger类提供的atomic方法可让这种操做具备原子性如getAndIncrement()方法会原子性的进行增量操做把当前值加一,其它数据类型和引用变量也能够进行类似操做。
Thread类的sleep()和yield()方法将在当前正在执行的线程上运行。因此在其余处于等待状态的线程上调用这些方法是没有意义的。这就是为何这些方法是静态的。它们能够在当前正在执行的线程中工做,并避免程序员错误的认为能够在其余非运行线程调用这些方法。
本文连接:Java高并发综合
做者:猴子007
出处:monkeysayhi.github.io
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布,欢迎转载,演绎或用于商业目的,可是必须保留本文的署名及连接。