作者:小傅哥
博客: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;        }    }
}
   复制代码
 
 韦春花与鳌大人喝茶、吟诗、做对、聊风月!韦春花与鳌大人喝茶、吟诗、做对、聊风月!韦春花与鳌大人喝茶、吟诗、做对、聊风月!韦春花与鳌大人喝茶、吟诗、做对、聊风月!老鸨敲门:时间到啦!
韦春花与陈近南喝茶、吟诗、做对、聊风月!韦春花与陈近南喝茶、吟诗、做对、聊风月!韦春花与陈近南喝茶、吟诗、做对、聊风月!韦春花与陈近南喝茶、吟诗、做对、聊风月!老鸨敲门:时间到啦!
韦春花与海大富喝茶、吟诗、做对、聊风月!韦春花与海大富喝茶、吟诗、做对、聊风月!韦春花与海大富喝茶、吟诗、做对、聊风月!韦春花与海大富喝茶、吟诗、做对、聊风月!老鸨敲门:时间到啦!
   复制代码
 
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 + ",进宫当太监,不用排队!");    }
}
   复制代码
 
 路人甲,排队等待进宫当杂役...韦小宝,进宫当太监,不用排队!路人甲,排队等待进宫当杂役...路人甲,排队等待进宫当杂役...路人甲,排队等待进宫当杂役...路人甲,排队等待进宫当杂役...路人甲,排队等待进宫当杂役...
   复制代码
 
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();    }
}
   复制代码
 
 韦小宝与皇上比武出招:小擒拿韦小宝与皇上比武出招:抓乃龙抓手韦小宝与皇上比武出招:下脚绊韦小宝与皇上比武出招:大别子韦小宝与皇上比武出招:锁喉韦小宝与皇上比武出招:扣眼珠子韦小宝与皇上比武出招:小擒拿韦小宝与皇上比武出招:抓乃龙抓手韦小宝与皇上比武出招:下脚绊韦小宝与皇上比武出招:大别子韦小宝与皇上比武出招:锁喉韦小宝与皇上比武出招:扣眼珠子韦小宝与皇上比武出招:小擒拿韦小宝与皇上比武出招:抓乃龙抓手韦小宝与皇上比武出招:下脚绊韦小宝与皇上比武出招:大别子韦小宝与皇上比武出招:锁喉
   复制代码
 
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();        }
    }
}
   复制代码
 
 韦小宝带着七个老婆,过着桃园生活。每天打打麻将、练练武术。麻将四人桌:曾柔韦小宝带着七个老婆,过着桃园生活。每天打打麻将、练练武术。麻将四人桌:苏荃韦小宝带着七个老婆,过着桃园生活。每天打打麻将、练练武术。麻将四人桌:双儿韦小宝带着七个老婆,过着桃园生活。每天打打麻将、练练武术。麻将四人桌:阿珂
韦小宝带着七个老婆,过着桃园生活。每天打打麻将、练练武术。麻将四人桌:方怡韦小宝带着七个老婆,过着桃园生活。每天打打麻将、练练武术。麻将四人桌:韦小宝韦小宝带着七个老婆,过着桃园生活。每天打打麻将、练练武术。麻将四人桌:建宁公主韦小宝带着七个老婆,过着桃园生活。每天打打麻将、练练武术。麻将四人桌:沐建屏
   复制代码
 
三、总结
- 在鹿鼎记的场景中我们串进去了各个多线程的使用案例,分别包括不同锁:- Synchronized、- CountDownLatch、- ReentrantLock、- ReentrantReadWriteLock、- Semaphore。
 
- 很多时候如果在学习的过程中,如果能找到一些非常适合的例子,那么对于知识点的学习是非常快的也能有深刻的印象。 
- 好嘞,这个案例就写完了,感谢支持。同时,这里面的各个场景中的多线程和锁也可以有不同的方式的使用来实现每个场景的效果,可以自行尝试。 
四、系列推荐
评论