作者:小傅哥
博客:https://bugstack.cn
Github:https://github.com/fuzhengwei/CodeGuide/wiki
积淀、分享、成长,让本人和别人都能有所播种!????
一、前言
学习门路决定学习效果!
有时候很多看似简单的常识,其实并没有多简单,只不过你找到的那份材料把常识 讲简单了
。为什么这么说呢?????
学习常识能够设想成是一个从 结尾接触
到结尾把常识吸纳
的过程,在这个过程中会有一些常识门路行走经验。那么不同的材料就是带着你在走这条常识门路,只不过有些材料容易绕路或者难走(路也跟车有关系,有些路适宜客车????、有些路适宜轿车????)。而当你找到一份十分不错并且适宜本人的材料时,就会有一种舒畅、通透的感觉,不会感觉学起来多简单,同时不仅学会了也了解了外围实质。这份材料在你手里就是,车速有点快、系好安全带
所以,能找到最好的材料也是学习过程中,十分重要的一个点。你的检索能力越强,你就会越容易找到最合适你的材料。
接下来小傅哥就带你进入 鹿鼎记 · 韦小宝
的多线程和锁
的故事路线,感触 逗 B
的学习路线!
二、韦小宝与多线程
小傅哥选取了五个鹿鼎记场景,融入进去不同的多线程应用,包含:丽春院,说书
、 天地会,香主
、 招收杂役,入宫
、 皇上、建宁,比武
、 七个老婆,隐居
,这样五个场景。 置信你看完后,肯定会记住每个线程的应用!
1. 丽春院,说书
public class SynchronizedTest {private static ExecutorService 丽春院 = Executors.newFixedThreadPool(10);
private static volatile boolean 老鸨 = false;
public static class 客官 implements Runnable {
private String 姓名;
public 客官(String 姓名) {this. 姓名 = 姓名;}
@Override
public void run() {
try {清倌(姓名);
} catch (InterruptedException e) {e.printStackTrace();
}
}
}
public static synchronized void 清倌(String 姓名) throws InterruptedException {while (true){System.out.println("韦春花与" + 姓名 + "喝茶、吟诗、做对、聊风月!");
if (老鸨){System.out.println("老鸨敲门:工夫到啦!\r\n");
老鸨 = false;
break;
}
Thread.sleep(1000);
}
}
private static List<String> list = Arrays.asList("鳌小孩儿", "陈近南", "海大富");
public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 3; i++) {丽春院.execute(new 客官(list.get(i)));
Thread.sleep(3000);
老鸨 = true;
}
}
}
- 场景 :韦小宝在丽春院打杂说书时,常有一些大佬(
鳌小孩儿
、陈近南
、海大富
)前来与清倌吟诗、做对、聊风月。但因为大家都观赏其中一个叫韦春花的清倌,所以须要排队。 - 常识 :应用
synchronized
锁,和volatile
可见性,一直的实例化客官
退出线程池,期待与清倌聊天。还能够应用 wait()、notify()来实现这一成果过程 - 测试后果:
韦春花与鳌小孩儿喝茶、吟诗、做对、聊风月!韦春花与鳌小孩儿喝茶、吟诗、做对、聊风月!韦春花与鳌小孩儿喝茶、吟诗、做对、聊风月!韦春花与鳌小孩儿喝茶、吟诗、做对、聊风月!老鸨敲门:工夫到啦!韦春花与陈近南喝茶、吟诗、做对、聊风月!韦春花与陈近南喝茶、吟诗、做对、聊风月!韦春花与陈近南喝茶、吟诗、做对、聊风月!韦春花与陈近南喝茶、吟诗、做对、聊风月!老鸨敲门:工夫到啦!韦春花与海大富喝茶、吟诗、做对、聊风月!韦春花与海大富喝茶、吟诗、做对、聊风月!韦春花与海大富喝茶、吟诗、做对、聊风月!韦春花与海大富喝茶、吟诗、做对、聊风月!老鸨敲门:工夫到啦!
2. 天地会,香主
public class CountDownLatchTest {public static void main(String[] args) throws InterruptedException {
List<String> list = Arrays.asList("总舵主,陈近南", "莲花堂香主,蔡德忠",
"洪顺堂香主,方大洪",
"家后堂香主,马超兴",
"参太堂香主,胡德帝",
"宏化堂香主,李式开",
"青木堂香主,韦小宝",
"赤火堂香主,古至中",
"玄水堂香主,林永超",
"黄土堂香主,姚必达");
CountDownLatch latch = new CountDownLatch(10);
ExecutorService exec = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
int idx = i;
exec.execute(() -> {
try {System.out.println("天地会外围十堂核心成员,高层会议,成员:" + list.get(idx) + "入场");
Thread.sleep(3000);
} catch (Exception ignore) { } finally {latch.countDown();
}
});
}
latch.await();
System.out.println("天地会,核心成员到齐。开会讨论谁入宫,偷取四十二章经!「内定韦香主」");
exec.shutdown();}
}
- 场景:韦小宝在丽春院营救陈近南后,退出了天地会还当上了青木堂韦香主,与其余九位香主齐名:洪顺堂、家后堂、参太堂、宏化堂、赤火堂、玄水堂、黄土堂。这也是天地会的核心成员,他们常常定期散会。这不,就开会讨论由谁入宫偷取四十二章经,其实曾经内定了韦香主·韦小宝。
- 常识:
CountDownLatch
门栓成果,满足肯定人数就开船、摇晃锤、过山车????。那么散会的成果也是应用这个锁来实现,满足 10 集体当前,关门开始。 - 测试后果:
天地会外围十堂核心成员,高层会议,成员:总舵主,陈近南 入场
天地会外围十堂核心成员,高层会议,成员:莲花堂香主,蔡德忠 入场
天地会外围十堂核心成员,高层会议,成员:洪顺堂香主,方大洪 入场
天地会外围十堂核心成员,高层会议,成员:家后堂香主,马超兴 入场
天地会外围十堂核心成员,高层会议,成员:参太堂香主,胡德帝 入场
天地会外围十堂核心成员,高层会议,成员:宏化堂香主,李式开 入场
天地会外围十堂核心成员,高层会议,成员:青木堂香主,韦小宝 入场
天地会外围十堂核心成员,高层会议,成员:赤火堂香主,古至中 入场
天地会外围十堂核心成员,高层会议,成员:玄水堂香主,林永超 入场
天地会外围十堂核心成员,高层会议,成员:黄土堂香主,姚必达 入场
天地会,核心成员到齐。开会讨论谁入宫,偷取四十二章经!「内定韦香主」
3. 招收杂役,入宫
public class ReentrantLockTest {private static ReentrantLock lock = new ReentrantLock(true);
private static List<String> list = Arrays.asList("路人甲", "路人乙", "路人丙", "路人丁", "路人戊", "路人己", "路人庚", "路人壬", "路人癸", "韦小宝");
public static void main(String[] args) {for (int i = 0; i < 10; i++) {
int idx = i;
new Thread(() -> {
try {招收杂役(list.get(idx));
} catch (InterruptedException ignore) {}}).start();
if (idx == 9) {new Thread(() -> {招收太监(list.get(idx));
}).start();}
}
}
public static void 招收杂役(String name) throws InterruptedException {lock.lock();
try {while (true) {System.out.println(name + ",排队期待进宫当杂役...");
Thread.sleep(1000);
}
} finally {lock.unlock();
}
}
public static void 招收太监(String name) {System.out.println(name + ",进宫当太监,不必排队!");
}
}
- 场景 :在被坑作为入宫人选好后,小宝来到了招募杂役的中央,一看排队好长。
眉头一皱; 计上心来
跑到了旁边,这边没有人排队呀!就立马冲了进去。咱们在案例中采纳偏心锁排队的形式来体现这一场景。 - 常识:
ReentrantLock
,偏心锁排队,在代码中须要显示的开启锁和敞开锁。 - 测试后果:
路人甲,排队期待进宫当杂役...
韦小宝,进宫当太监,不必排队!路人甲,排队期待进宫当杂役...
路人甲,排队期待进宫当杂役...
路人甲,排队期待进宫当杂役...
路人甲,排队期待进宫当杂役...
路人甲,排队期待进宫当杂役...
4. 皇上、建宁,比武
public class ReentrantReadWriteLockTest {private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private static final Lock readLock = readWriteLock.readLock();
private static final Lock writeLock = readWriteLock.writeLock();
private static Deque<String> deque = new ArrayDeque<>();
public static String get() {readLock.lock();
try {return deque.poll();
} finally {readLock.unlock();
}
}
public static void put(String value) {writeLock.lock();
try {deque.add(value);
} finally {writeLock.unlock();
}
}
public static void main(String[] args) {new Thread(() -> {while (true) {put("小擒拿");
put("抓乃龙抓手");
put("下脚绊");
put("大别子");
put("锁喉");
put("扣眼珠子");
try {Thread.sleep(3000);
} catch (InterruptedException ignore) {}}
}).start();
new Thread(() -> {while (true) {System.out.println("韦小宝与皇上比武出招:" + get());
try {Thread.sleep(500);
} catch (InterruptedException ignore) {}}
}).start();}
}
- 场景 :在海大富的帮忙下蒙混进宫偷四十二章经时,不小心被建宁公主发现,为此引来这样一段打斗比武的场景。小宝不会文治,每天学会点再比试点,因而咱们这里应用读写锁来模仿。 写锁相当于传授常识、读锁相当于应用常识
- 常识:
ReentrantReadWriteLock
对于读写锁的应用。 - 测试后果:
韦小宝与皇上比武出招:小擒拿
韦小宝与皇上比武出招:抓乃龙抓手
韦小宝与皇上比武出招:下脚绊
韦小宝与皇上比武出招:大别子
韦小宝与皇上比武出招:锁喉
韦小宝与皇上比武出招:扣眼珠子
韦小宝与皇上比武出招:小擒拿
韦小宝与皇上比武出招:抓乃龙抓手
韦小宝与皇上比武出招:下脚绊
韦小宝与皇上比武出招:大别子
韦小宝与皇上比武出招:锁喉
韦小宝与皇上比武出招:扣眼珠子
韦小宝与皇上比武出招:小擒拿
韦小宝与皇上比武出招:抓乃龙抓手
韦小宝与皇上比武出招:下脚绊
韦小宝与皇上比武出招:大别子
韦小宝与皇上比武出招:锁喉
5. 七个老婆,隐居
public class SemaphoreTest {public static void main(String[] args) {List<String> list = new ArrayList<>();
list.add("韦小宝");
list.add("阿珂");
list.add("双儿");
list.add("曾柔");
list.add("建宁公主");
list.add("沐建屏");
list.add("方怡");
list.add("苏荃");
Semaphore semaphore = new Semaphore(4, true);
for (int i = 0; i < 8; i++) {new Thread(() -> {
try {semaphore.acquire();
String user = list.remove(new Random().nextInt(list.size()));
System.out.println("韦小宝带着七个老婆,过着桃园生存。每天打打麻将、练练武术。麻将四人桌:" + user);
Thread.sleep(3000L);
} catch (InterruptedException ignore) { } finally {semaphore.release();
}
}).start();}
}
}
- 场景 :经验了风风雨雨的小宝,最初决定和老婆们过起高兴的隐居生存。咱们这里模仿隐居桃园后,每天打打麻将、练练武术,凑够一桌四人。 这里咱们应用信号量锁 Semaphore,一次凑够四个人就够一桌麻将的人。
随机抽取四个人
- 常识:
Semaphore
信号量锁的应用 - 测试后果:
韦小宝带着七个老婆,过着桃园生存。每天打打麻将、练练武术。麻将四人桌:曾柔
韦小宝带着七个老婆,过着桃园生存。每天打打麻将、练练武术。麻将四人桌:苏荃
韦小宝带着七个老婆,过着桃园生存。每天打打麻将、练练武术。麻将四人桌:双儿
韦小宝带着七个老婆,过着桃园生存。每天打打麻将、练练武术。麻将四人桌:阿珂
韦小宝带着七个老婆,过着桃园生存。每天打打麻将、练练武术。麻将四人桌:方怡
韦小宝带着七个老婆,过着桃园生存。每天打打麻将、练练武术。麻将四人桌:韦小宝
韦小宝带着七个老婆,过着桃园生存。每天打打麻将、练练武术。麻将四人桌:建宁公主
韦小宝带着七个老婆,过着桃园生存。每天打打麻将、练练武术。麻将四人桌:沐建屏
三、总结
- 在鹿鼎记的场景中咱们串进去了各个多线程的应用案例,别离包含不同锁:
Synchronized
、CountDownLatch
、ReentrantLock
、ReentrantReadWriteLock
、Semaphore
。 - 很多时候如果在学习的过程中,如果能找到一些非常适合的例子,那么对于知识点的学习是十分快的也能有粗浅的印象。
- 好嘞,这个案例就写完了,感激反对。同时,这外面的各个场景中的多线程和锁也能够有不同的形式的应用来实现每个场景的成果,能够自行尝试。
四、系列举荐
- 一次代码评审,差点过不了试用期!
- 大厂招聘,和 Java 程序员都聊什么?
- 程序员为什么热衷于造轮子,升职加薪吗?
- 深刻学习 Java,横扫大厂 Offer
- 重学 Java 设计模式,全网下载 10 万 +