Skip to content

Commit

Permalink
Add episode 23
Browse files Browse the repository at this point in the history
  • Loading branch information
mercyblitz committed Apr 13, 2019
1 parent 038f5bf commit f8232b1
Show file tree
Hide file tree
Showing 27 changed files with 1,109 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.imooc.interview.questions.java.concurrency.atomic;

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicQuestion {

private static int actualValue = 3;

public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(3);
// if( value == 3 )
// value = 5
atomicInteger.compareAndSet(3, 5);
// 偏向锁 < CAS 操作 < 重锁(完全互斥)
// CAS 操作也是相对重的操作,它也是实现 synchronized 瘦锁(thin lock)的关键
// https://wiki.openjdk.java.net/display/HotSpot/Synchronization
// 偏向锁就是避免 CAS(Compare And Set/Swap)操作
// 汇编指令:cpmxchg
}

private synchronized static void compareAndSet(int expectedValue, int newValue) {
if (actualValue == expectedValue) {
actualValue = newValue;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.imooc.interview.questions.java.concurrency.barrier;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchQuestion {

public static void main(String[] args) throws InterruptedException {

// 倒数计数 5
CountDownLatch latch = new CountDownLatch(5);

ExecutorService executorService = Executors.newFixedThreadPool(5);

for (int i = 0; i < 4; i++) {
executorService.submit(() -> {
action();
latch.countDown(); // -1
});
}

// 等待完成
// 当计数 > 0,会被阻塞
latch.await();

System.out.println("Done");

// 关闭线程池
executorService.shutdown();
}

private static void action() {
System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.imooc.interview.questions.java.concurrency.barrier;

import java.util.concurrent.*;

public class CyclicBarrierQuestion {

public static void main(String[] args) throws InterruptedException {

CyclicBarrier barrier = new CyclicBarrier(5); // 5

ExecutorService executorService = Executors.newFixedThreadPool(5); // 3

for (int i = 0; i < 20; i++) {
executorService.submit(() -> {
action();
try {
// CyclicBarrier.await() = CountDownLatch.countDown() + await()
// 先计数 -1,再判断当计数 > 0 时候,才阻塞
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
});
}

// 尽可能不要执行完成再 reset
// 先等待 3 ms
executorService.awaitTermination(3, TimeUnit.MILLISECONDS);
// 再执行 CyclicBarrier reset
// reset 方法是一个废操作
barrier.reset();

System.out.println("Done");

// 关闭线程池
executorService.shutdown();
}

private static void action() {
System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.imooc.interview.questions.java.concurrency.barrier;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LegacyCountDownLatchDemo {

public static void main(String[] args) throws InterruptedException {

// 倒数计数 5
MyCountDownLatch latch = new MyCountDownLatch(5);

ExecutorService executorService = Executors.newFixedThreadPool(5);

for (int i = 0; i < 5; i++) {
executorService.submit(() -> {
action();
latch.countDown(); // -1
});
}

// 等待完成
// 当计数 > 0,会被阻塞
latch.await();

System.out.println("Done");

// 关闭线程池
executorService.shutdown();
}

private static void action() {
System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2
}

/**
* Java 1.5+ Lock 实现
*/
private static class MyCountDownLatch {

private int count;

private final Lock lock = new ReentrantLock();

private final Condition condition = lock.newCondition();

private MyCountDownLatch(int count) {
this.count = count;
}

public void await() throws InterruptedException {
// 当 count > 0 等待
if (Thread.interrupted()) {
throw new InterruptedException();
}

lock.lock();
try {
while (count > 0) {
condition.await(); // 阻塞当前线程
}
} finally {
lock.unlock();
}
}

public void countDown() {

lock.lock();
try {
if (count < 1) {
return;
}
count--;
if (count < 1) { // 当数量减少至0时,唤起被阻塞的线程
condition.signalAll();
}
} finally {
lock.unlock();
}
}
}

/**
* Java < 1.5 实现
*/
private static class LegacyCountDownLatch {

private int count;

private LegacyCountDownLatch(int count) {
this.count = count;
}

public void await() throws InterruptedException {
// 当 count > 0 等待
if (Thread.interrupted()) {
throw new InterruptedException();
}

synchronized (this) {
while (count > 0) {
wait(); // 阻塞当前线程
}
}
}

public void countDown() {
synchronized (this) {
if (count < 1) {
return;
}
count--;
if (count < 1) { // 当数量减少至0时,唤起被阻塞的线程
notifyAll();
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.imooc.interview.questions.java.concurrency.collection;

import java.util.Arrays;
import java.util.List;

public class ArraysAsListMethodQuestion {

public static void main(String[] args) {

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 调整第三个元素为 9
list.set(2, 9);
// 3 -> 9
// Arrays.asList 并非线程安全
list.forEach(System.out::println);
// Java < 5 , Collections#synchronizedList
// Java 5+ , CopyOnWriteArrayList
// Java 9+ , List.of(...) 只读
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.imooc.interview.questions.java.concurrency.collection;

import java.util.concurrent.*;

public class BlockingQueueQuiz {

public static void main(String[] args) throws Exception {
offer(new ArrayBlockingQueue<>(2));
offer(new LinkedBlockingQueue<>(2));
offer(new PriorityBlockingQueue<>(2));
offer(new SynchronousQueue<>());
}

private static void offer(BlockingQueue<Integer> queue) throws Exception {
System.out.println("queue.getClass() = " + queue.getClass().getName());
System.out.println("queue.offer(1) = " + queue.offer(1));
System.out.println("queue.offer(2) = " + queue.offer(2));
System.out.println("queue.offer(3) = " + queue.offer(3));
System.out.println("queue.size() = " + queue.size());
System.out.println("queue.take() = " + queue.take());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.imooc.interview.questions.java.concurrency.collection;

import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashSetQuestion {


public static void main(String[] args) {

}

private static class ConcurrentHashSet<E> implements Set<E> {

private final Object OBJECT = new Object();

private final ConcurrentHashMap<E, Object> map = new ConcurrentHashMap<>();

private Set<E> keySet() {
return map.keySet();
}

@Override
public int size() {
return keySet().size();
}

@Override
public boolean isEmpty() {
return keySet().isEmpty();
}

@Override
public boolean contains(Object o) {
return keySet().contains(o);
}

@Override
public Iterator<E> iterator() {
return keySet().iterator();
}

@Override
public Object[] toArray() {
return new Object[0];
}

@Override
public <T> T[] toArray(T[] a) {
return null;
}

@Override
public boolean add(E e) {
return map.put(e, OBJECT) == null;
}

@Override
public boolean remove(Object o) {
return map.remove(o) != null;
}

@Override
public boolean containsAll(Collection<?> c) {
return false;
}

@Override
public boolean addAll(Collection<? extends E> c) {
return false;
}

@Override
public boolean retainAll(Collection<?> c) {
return false;
}

@Override
public boolean removeAll(Collection<?> c) {
return false;
}

@Override
public void clear() {

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.imooc.interview.questions.java.concurrency.collection;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class PriorityBlockingQueueQuiz {

public static void main(String[] args) throws Exception {
BlockingQueue<Integer> queue = new PriorityBlockingQueue<>(2);
// 1. PriorityBlockingQueue put(Object) 方法不阻塞
// 2. PriorityBlockingQueue offer(Object) 方法不限制
// 3. PriorityBlockingQueue 插入对象会做排序,默认参照元素 Comparable 实现,
// 或者显示地传递 Comparator
queue.put(9);
queue.put(1);
queue.put(8);
System.out.println("queue.size() = " + queue.size());
System.out.println("queue.take() = " + queue.take());
System.out.println("queue = " + queue);
}
}
Loading

0 comments on commit f8232b1

Please sign in to comment.