1. 集合线程安全
package interview;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
public class Demo01ContainerNotSafeDemo {
public static void main(String[] args) {
mapNotSafe();
}
public static void mapNotSafe() {
Map<String, String> map = new ConcurrentHashMap<>();
for (int i = 0; i <= 30; i++) {
new Thread(() -> {
map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 8));
}, String.valueOf(i)).start();
}
}
public static void setNotSafe() {
Set<String> set = new CopyOnWriteArraySet<>();
for (int i = 0; i <= 30; i++) {
new Thread(() -> {
set.add(UUID.randomUUID().toString().substring(0, 8));
}, String.valueOf(i)).start();
}
}
public static void listNotSafe() {
List<String> list = new ArrayList<>();
for (int i = 0; i <= 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
}, String.valueOf(i)).start();
}
}
}
2. 锁机制
package interview;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;
class Phone{
public synchronized void sendSMS() throws Exception {
System.out.println(Thread.currentThread().getId() + "\t invoked sendSMS()");
sendEmail();
}
public synchronized void sendEmail() throws Exception {
System.out.println(Thread.currentThread().getId() + "\t invoked sendEmail()");
}
}
class MyCache {
private volatile Map<String, Object> map = new HashMap<>();
private ReentrantReadWriteLock rwlLock = new ReentrantReadWriteLock();
public void put(String key, Object value) {
rwlLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "\t 正在写入:" + key);
try {TimeUnit.SECONDS.sleep(300);} catch (Exception e) {e.printStackTrace();}
map.put(key, value);
System.out.println(Thread.currentThread().getName() + "\t 写入完成");
} catch (Exception e) {
e.printStackTrace();
}finally {
rwlLock.writeLock().unlock();
}
}
public void get(String key) {
rwlLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "\t 正在读取:");
try {TimeUnit.SECONDS.sleep(300);} catch (Exception e) {e.printStackTrace();}
Object result = map.get(key);
System.out.println(Thread.currentThread().getName() + "\t 读取完成:" + result);
} catch (Exception e) {
e.printStackTrace();
}finally {
rwlLock.readLock().unlock();
}
}
}
public class Demo02Lock {
public static void main(String[] args) {
}
public static void ReadWriteLock() {
MyCache cache = new MyCache();
for (int i = 0; i <= 5; i++) {
final int tempInt = i;
new Thread(() -> {
cache.put(tempInt + "", tempInt + "");
}, String.valueOf(i)).start();
}
for (int i = 0; i <= 5; i++) {
final int tempInt = i;
new Thread(() -> {
cache.get(tempInt + "");;
}, String.valueOf(i)).start();
}
}
AtomicReference<Thread> atomicReference = new AtomicReference<>();
public static void SpinLock() {
Demo02Lock lock = new Demo02Lock();
new Thread(() -> {
lock.myLock();
try {TimeUnit.SECONDS.sleep(5);} catch (Exception e) {e.printStackTrace();}
lock.unMyLock();
}, "AA").start();
try {TimeUnit.SECONDS.sleep(1);} catch (Exception e) {e.printStackTrace();}
new Thread(() -> {
lock.myLock();
lock.unMyLock();
}, "BB").start();
}
public void myLock() {
Thread thread = new Thread();
while(!atomicReference.compareAndSet(null, thread)) {
}
}
public void unMyLock() {
Thread thread = new Thread();
atomicReference.compareAndSet(thread, null);
}
public static void Reentrant() {
Phone phone = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t1").start();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t2").start();
}
}
3. CountDownLatch
package interview;
import java.util.concurrent.CountDownLatch;
enum CountryEnum {
ONE(1, "齐"), TWO(2, "楚"), THREE(3, "燕"), FOUR(4, "赵"), FIVE(5, "魏"), SIX(6, "韩");
private Integer retCode;
private String retMessage;
public Integer getRetCode() {
return retCode;
}
public String getRetMessage() {
return retMessage;
}
CountryEnum(Integer retCode, String retMessage) {
this.retCode = retCode;
this.retMessage = retMessage;
}
public static CountryEnum forEach_CountryEnum(int index) {
CountryEnum[] myArray = CountryEnum.values();
for (CountryEnum element : myArray) {
if(index == element.getRetCode()) {
return element;
}
}
return null;
}
}
public class Demo03CountDownLatch {
public static void main(String[] args) throws Exception{
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t 国,被灭");
countDownLatch.countDown();
}, CountryEnum.forEach_CountryEnum(i).getRetMessage()).start();
}
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "\t 秦帝国,一统华夏");
}
public static void closeDoor() throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t 上完自习,离开教室");
countDownLatch.countDown();
}, String.valueOf(i)).start();
}
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "\t 班长最后关门走人");
}
}
4. CyclicBarrier
package interview;
import java.util.concurrent.CyclicBarrier;
public class Demo04CyclicBarrier {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {System.out.println("***召唤神龙");});
for (int i = 1; i <= 7; i++) {
final int tempInt = i;
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t 收集到第:" + tempInt + "龙珠");
try {
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}, String.valueOf(i)).start();
}
}
}
5. Semaphore
package interview;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class Demo05Semaphore {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "\t抢到车位");
try {TimeUnit.SECONDS.sleep(3);} catch (Exception e) {e.printStackTrace();};
System.out.println(Thread.currentThread().getName() + "\t停车3秒后离开车位");
} catch (Exception e) {
e.printStackTrace();
}finally {
semaphore.release();
}
}, String.valueOf(i)).start();
}
}
}
6. BlockingQueue
package interview;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
public class Demo06BlockingQueue {
public static void main(String[] args) throws Exception{
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.add("a");
blockingQueue.add("b");
blockingQueue.add("c");
System.out.println(blockingQueue.element());
blockingQueue.remove();
blockingQueue.remove();
blockingQueue.remove();
blockingQueue.offer("a");
blockingQueue.offer("b");
blockingQueue.offer("c");
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.peek());
blockingQueue.poll();
blockingQueue.poll();
blockingQueue.poll();
System.out.println(blockingQueue.poll());
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
blockingQueue.take();
blockingQueue.take();
blockingQueue.take();
blockingQueue.offer("a", 2L, TimeUnit.SECONDS);
blockingQueue.offer("b", 2L, TimeUnit.SECONDS);
blockingQueue.offer("c", 2L, TimeUnit.SECONDS);
blockingQueue.offer("d", 2L, TimeUnit.SECONDS);
}
}
7. SynchronousQueue
package interview;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
public class Demo07SynchronousQueue {
public static void main(String[] args) {
BlockingQueue<String> blockingQueue = new SynchronousQueue<>();
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + "\t put 1");
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName() + "\t put 2");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName() + "\t put 3");
blockingQueue.put("3");
} catch (Exception e) {
e.printStackTrace();
}
}, "AAA").start();
new Thread(() -> {
try {
try {TimeUnit.SECONDS.sleep(5);} catch (Exception e) {e.printStackTrace();}
System.out.println(Thread.currentThread().getName() + "\t take " + blockingQueue.take());
try {TimeUnit.SECONDS.sleep(5);} catch (Exception e) {e.printStackTrace();}
System.out.println(Thread.currentThread().getName() + "\t take " + blockingQueue.take());
try {TimeUnit.SECONDS.sleep(5);} catch (Exception e) {e.printStackTrace();}
System.out.println(Thread.currentThread().getName() + "\t take " + blockingQueue.take());
} catch (Exception e) {
e.printStackTrace();
}
}, "BBB").start();
}
}
8. 生产者与消费者
8.1 传统实现方式
package interview;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareData {
private int number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void increment() throws Exception {
lock.lock();
try {
while(number != 0) {
condition.await();
}
number++;
System.out.println(Thread.currentThread().getName() + "\t" + number);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void decrement() throws Exception {
lock.lock();
try {
while(number == 0) {
condition.await();
}
number--;
System.out.println(Thread.currentThread().getName() + "\t" + number);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
public class Demo08ProdConsumer_Tradition {
public static void main(String[] args) {
ShareData shareData = new ShareData();
new Thread(() -> {
for (int i = 1; i <= 5; i++) {
try {
shareData.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "AA").start();
new Thread(() -> {
for (int i = 1; i <= 5; i++) {
try {
shareData.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "BB").start();
}
}
8.2 多条件绑定
package interview;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareResource{
private int number = 1;
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public void print5() {
lock.lock();
try {
while(number != 1) {
c1.await();
}
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i);
}
number = 2;
c2.signal();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void print10() {
lock.lock();
try {
while(number != 2) {
c2.await();
}
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i);
}
number = 3;
c3.signal();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void print15() {
lock.lock();
try {
while(number != 3) {
c3.await();
}
for (int i = 1; i <= 15; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i);
}
number = 1;
c1.signal();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
public class Demo09SyncAndReentrantLock {
public static void main(String[] args) {
ShareResource shareResource = new ShareResource();
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
shareResource.print5();
}
}, "AA").start();
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
shareResource.print10();
}
}, "BB").start();
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
shareResource.print15();
}
}, "CC").start();
}
}
8.3 阻塞队列实现
package interview;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
class MyResource{
private volatile boolean FLAG = true;
private AtomicInteger atomicInteger = new AtomicInteger();
BlockingQueue<String> blockingQueue = null;
public MyResource(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
System.out.println(blockingQueue.getClass().getName());
}
public void myProd() throws Exception {
String data = null;
boolean retValue = false;
while(FLAG) {
data = atomicInteger.incrementAndGet() + "";
retValue = blockingQueue.offer(data, 2L, TimeUnit.SECONDS);
if(retValue) {
System.out.println(Thread.currentThread().getName() + "\t 插入队列" + data + "成功");
}else {
System.out.println(Thread.currentThread().getName() + "\t 插入队列" + data + "失败");
}
TimeUnit.SECONDS.sleep(1);
}
System.out.println(Thread.currentThread().getName() + "\t大老板叫停了,表示FLAG=false,生产动作结束");
}
public void myConsumer() throws Exception {
String result = null;
while(FLAG) {
result = blockingQueue.poll(2L, TimeUnit.SECONDS);
if(result == null || result.equalsIgnoreCase("")) {
FLAG = false;
System.out.println(Thread.currentThread().getName() + "\t超过2秒钟没有取到蛋糕,消费退出");
return;
}
System.out.println(Thread.currentThread().getName() + "\t 消费队列" + result + "成功");
}
}
public void stop() throws Exception {
this.FLAG = false;
}
}
public class Demo10ProdConsumer_BlockQueue {
public static void main(String[] args) {
MyResource myResource = new MyResource(new ArrayBlockingQueue<>(10));
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t生产线程启动");
try {
myResource.myProd();
} catch (Exception e) {
e.printStackTrace();
}
}, "Prod").start();
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t消费线程启动");
try {
myResource.myConsumer();
} catch (Exception e) {
e.printStackTrace();
}
}, "Consumer").start();
try {TimeUnit.SECONDS.sleep(5);} catch (Exception e) {e.printStackTrace();}
System.out.println("5秒钟后停止生产消费");
try {
myResource.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
9. 线程池
package interview;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Demo12ThreadPool {
public static void main(String[] args) {
}
public static void initThreadPool() {
ExecutorService threadPool = new ThreadPoolExecutor(2,
5,
1L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy() );
try {
for (int i = 1; i <= 10; i++) {
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "\t 办理业务");
});
}
} catch (Exception e) {
e.printStackTrace();
}finally {
threadPool.shutdown();
}
}
public static void ThreadPool() {
ExecutorService threadPool = Executors.newFixedThreadPool(5);
try {
for (int i = 1; i <= 10; i++) {
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "\t 办理业务");
});
}
} catch (Exception e) {
e.printStackTrace();
}finally {
threadPool.shutdown();
}
}
}