最近一直整并发这块东西,顺便写点Java并发的例子,给大家做个分享,也强化下自己记忆,如果有什么错误或者不当的地方,欢迎大家斧正。

LOL和王者荣耀的玩家很多,许多人应该都有打大龙的经历,话说前期大家打算一起去偷大龙,由于前期大家都比较弱,需要五个人都齐了才能打大龙,这样程序该如何实现呢?本人很菜,开始我的代码是这么写的(哈哈大家不要纠结我的时间):

public class KillDragon {
    /**
     * 模拟打野去打大龙
     */
   public static void dayePlayDragon(){
       System.out.println("打野在去打大龙的路上,需要10s");
   }

    /**
     * 模拟上单去打大龙
     */
    public static void shangdanPlayDragon(){
        System.out.println("上单在去打大龙的路上,需要10s");
    }

    /**
     * 模拟中单去打大龙
     */
    public static void zhongdanPlayDragon(){
        System.out.println("中单在去打大龙的路上,需要10s");
    }

    /**
     * 模拟ADC和辅助去打大龙
     */
    public static void adcAndFuzhuPlayDragon(){
        System.out.println("ADC和辅助在去打大龙的路上,需要10s");
    }

    /**
     * 模拟大家一起去打大龙
     */
    public static void killDragon()
    {
        System.out.println("打大龙...");
    }

    public static void main(String[] args)
    {
        dayePlayDragon();
        shangdanPlayDragon();
        zhongdanPlayDragon();
        adcAndFuzhuPlayDragon();
        killDragon();
    }

  结果如下:

打野在去打大龙的路上,需要10s
上单在去打大龙的路上,需要10s
中单在去打大龙的路上,需要10s
ADC和辅助在去打大龙的路上,需要10s
打大龙...

  这完了,大家在路上的时间就花了40s了,显然是错误的。要是都这么干,对方把你塔都要偷光了。不行得改进下,怎么改呢,多线程并发执行,如是我改成了下面这样的,用volatile关键字。

private static volatile int i = 4;
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                long start = System.currentTimeMillis();
                while (i!=0){

                }
                while (i==0) {
                    killDragon();
                    i--;
                    long t = System.currentTimeMillis() - start;
                    System.out.println("总共耗时:"+t+"毫秒");
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                dayePlayDragon();
                try {
                    Thread.sleep(10000);
                    i--;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                shangdanPlayDragon();
                try {
                    Thread.sleep(10000);
                    i--;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                zhongdanPlayDragon();
                try {
                    Thread.sleep(10000);
                    i--;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                adcAndFuzhuPlayDragon();
                try {
                    Thread.sleep(10000);
                    i--;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

  结果如下:

打野在去打大龙的路上,需要10s
上单在去打大龙的路上,需要10s
中单在去打大龙的路上,需要10s
ADC和辅助在去打大龙的路上,需要10s
打大龙...
总共耗时:10005毫秒

  结果似乎还不错,但是处理起来实在是有点麻烦,需要 while (i!=0)一直在那循环着。这时候学到了用 CyclicBarrier来处理,代码如下:

public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(5);
        new Thread(new Runnable() {
            @Override
            public void run() {
                long start = System.currentTimeMillis();
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                killDragon();
                long t = System.currentTimeMillis() - start;
                System.out.println("总共耗时:"+t+"毫秒");
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                dayePlayDragon();
                try {
                    Thread.sleep(10000);
                    barrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                shangdanPlayDragon();
                try {
                    Thread.sleep(10000);
                    barrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                zhongdanPlayDragon();
                try {
                    Thread.sleep(10000);
                    barrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                adcAndFuzhuPlayDragon();
                try {
                    Thread.sleep(10000);
                    barrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

  大家都没到达之前都等待,结果如下:

打野在去打大龙的路上,需要10s
上单在去打大龙的路上,需要10s
中单在去打大龙的路上,需要10s
ADC和辅助在去打大龙的路上,需要10s
打大龙...
总共耗时:10002毫秒

  CyclicBarrier相当于线程的计数器:

  1. CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。
  2. CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。
  3. CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。

CyclicBarrier的使用之王者荣耀打大龙的更多相关文章

  1. 王者荣耀是怎样炼成的(一)《王者荣耀》用什么开发,游戏入门,unity3D介绍

    在国内,如果你没有听说过<王者荣耀>,那你一定是古董级的人物了. <王者荣耀>(以下简称“农药”),专注于移动端(Android.IOS)的MOBA游戏.笔者看到这么火爆,就萌 ...

  2. Unity 使用 陀螺仪 实现 《王者荣耀》 登入界面 背景动态效果

    在 <王者荣耀> 登入界面 左右上下晃动手机(有些手机不支持)可以看到背景在变化 我使用的是iPhone SE 效果如下: 对比两张图片的左下角 可以看到差异 至于为什么要这么做: 1.使 ...

  3. CNN网络介绍与实践:王者荣耀英雄图片识别

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者介绍:高成才,腾讯Android开发工程师,2016.4月校招加入腾讯,主要负责企鹅电竞推流SDK.企鹅电竞APP的功能开发和技术优化工作 ...

  4. 浅谈canvas绘画王者荣耀--雷达图

    背景: 一日晚上下班的我静静的靠在角落上听着歌,这时"滴!滴!"手机上传来一阵qq消息.原来我人在问王者荣耀的雷达图在页面上如何做出来的,有人回答用canvas绘画.那么问题来了, ...

  5. 用python的requests第三方模块抓取王者荣耀所有英雄的皮肤

    本文使用python的第三方模块requests爬取王者荣耀所有英雄的图片,并将图片按每个英雄为一个目录存入文件夹中,方便用作桌面壁纸 下面时具体的代码,已通过python3.6测试,可以成功运行: ...

  6. PYTHON-面向对象-练习-王者荣耀 对砍游戏

    # 王者荣耀 对砍游戏# 两个英雄可以对砍 如果血量小于等于0 就GG# 所需的对象# 英雄对象""" 亚瑟 属性 类型 血量 名称 技能 Q 跳起来给你一刀 伤害50 ...

  7. 王者荣耀里拿个王者有啥了不起,有胆就来挑战一下ApsaraCache源码

    王者荣耀大家估计都玩的很溜吧,撸完代码开一局,只要不遇到个猪队友,拿个鲁班后羿估计你们都能爆掉对手的塔吧.大神们打个排位赛拿个王者就和吃饭夹菜一样简单... But...你们玩过Redis和Memca ...

  8. Beta周第14次Scrum会议(11/23)【王者荣耀交流协会】

    一.小组信息 队名:王者荣耀交流协会 小组成员 队长:高远博 成员:王超,袁玥,任思佳,王磊,王玉玲,冉华 小组照片 二.开会信息 时间:2017/11/23 17:02~17:14,总计12min. ...

  9. Beta周第7次Scrum会议(11/16)【王者荣耀交流协会】

    一.小组信息 队名:王者荣耀交流协会 小组成员 队长:高远博 成员:王超,袁玥,任思佳,王磊,王玉玲,冉华 小组照片 二.开会信息 时间:2017/11/16 17:03~17:17,总计14min. ...

随机推荐

  1. Servlet3.1上传图片示例

    一.前端JSP页面 <%@page pageEncoding="UTF-8"%><!DOCTYPE html><html><head> ...

  2. 【LCT】一步步地解释Link-cut Tree

    简介 Link-cut Tree,简称LCT. 干什么的?它是树链剖分的升级版,可以看做是动态的树剖. 树剖专攻静态树问题:LCT专攻动态树问题,因为此时的树剖面对动态树问题已经无能为力了(动态树问题 ...

  3. 部署和使用kibana

    背景 上一篇介绍了在阿里云上部署ES,本文将主要介绍ELK的可视化工具Kibana的部署和使用.主要分为三个步骤来实现最终呈现: 1.导入数据到ES: 2.部署kibana并完成配置: 3.使用kib ...

  4. 推广技巧:新站要如何推广引流做到日IP10000?

    一.回复高人气帖子插楼推广 1.找高人气的帖子在二楼或者二楼楼层中直接插入链接推广.虽然这种方法存活率比较低,但也算是贴吧里面最直接的有效的方法.一般我们分为三种: 1.1图中链接是一个短网址,这个是 ...

  5. poj2901 Hotel

    Hotel Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 859   Accepted: 280 Description ...

  6. python基础教程(八)

    创建自已的对象(类)是python非常核心的概念,事实上,python被称为面向对象语言,本章会介绍如何创建对象.以及面向对象的概念:继承.封装.多态. 多态: 可对不同类的对象使用同样的操作. 封装 ...

  7. FileDetector-基于java开发的照片整理工具

    1. 项目背景 开发这个功能的主要原因如下: 1. 大学期间拍摄了约50G的照片,照片很多 2. 存放不规范,导致同一张照片出现在不同的文件夹内,可读性差,无法形成记忆线. 3. 重复存放过多,很多照 ...

  8. Centos 7系统启动修复

    author:JevonWei 版权声明:原创作品 错误界面 这个错误界面应该为/boot文件损坏,故应该修复/boot和grub2 修复/boot及grub 1 . chroot /mnt/sysi ...

  9. 使用设置sa用户登录sql server2008

    今天在net项目中添加数据库过程中出现了小问题,就是使用sql server身份验证没登录成功,经过一番调试,终于解决问题. 使用sa账户登录sql server 2008 的方法步骤如下: 1.首先 ...

  10. PHP(函数)

    <script> // 获得日 var time = new Date(); var x = time.getDate(); document.write(x+"日," ...