0%

synchronized

wait + notify/notifyAll

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Share {
private int number = 0;
public synchronized void incr() {
while(number != 0) {
this.wait();
}
number++;
this.notifyAll();
}
public synchronized void decr() {
while(number != 1) {
this.wait();
}
number--;
this.notifyAll();
}
}
Read more »

原理

  • CAS 是 JDK 提供的非阻塞原子性操作,其通过硬件保证了比较-更新的原子性
  • 实现方法:通过Unsafe提供的 CAS 方法(compareAndSwapXxx),底层实现是基于硬件平台的汇编指令,在 intel 的 CPU 中(x86机器上),使用的是汇编指令cmpxchg指令
  • 核心思想:比较要更新变量的值V和预期值E(compare),相等才会将V的值设为新值N(swap),如果不相等则自旋
  • 比起用synchronized重量级锁,CAS 的排他时间要短很多,因此在多线程情况下性能会比较好
Read more »

BlockingQueue

  • 阻塞:在某些情况下会挂起线程(即阻塞),一旦条件满足,被挂起的线程又会自动被唤起
    • 当队列是空的,从队列中获取元素的操作将会被阻塞
    • 当队列是满的,从队列中添加元素的操作将会被阻塞
    • 试图从空的队列中获取元素的线程将会被阻塞,直到其他线程往空的队列插入新的元素
    • 试图向已满的队列中添加新元素的线程将会被阻塞,直到其他线程从队列中移除一个或多 个元素或者完全清空,使队列变得空闲起来并后续新增
  • 使用阻塞队列的原因:多线程环境中,通过队列可以很容易实现数据共享
    • 经典的“生产者”和 “消费者”模型中,通过队列可以很便利地实现两者之间的数据共享
    • 当队列中没有数据的情况下,消费者端的所有线程都会被自动阻塞(挂起), 直到有数据放入队列,消费线程被自动唤醒
    • 当队列中填满数据的情况下,生产者端的所有线程都会被自动阻塞(挂起), 直到队列中有空的位置,生产线程被自动唤醒
Read more »

Future 不足之处

Future在 Java 里通常用来表示一个异步任务的引用,比如将任务提交到线程池里面,会得到一个Future,在Future里面有isDone方法来判断任务是否结束,get方法来一直阻塞知道任务结束然后获取结果

Read more »