最近一直整并发这块东西,顺便写点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. 记录-新建一个web应用的过程与曲折

    第一步/ 打开eclipse,菜单栏下,File–New–Other-,打开后找到web–Dynamic Web Project,然后单击Next. 解释一下,Dynamic ,动态的,变化的,Dyn ...

  2. C语言:freopen函数

    当我们求解acm题目时,通常在设计好算法和程序后,要在调试环境(例如VC等)中运行程序,输入测试数据,当能得到正确运行结果后,才将程序提交到oj中.但由于调试往往不能一次成功,每次运行时,都要重新输入 ...

  3. jsp页面附件上传暂存的处理

    有没有遇到页面是新建一个新对象,对象里面需要上传附件,但是只有当对象保存时才将附件一同上传到数据库的情况? 这种情况的处理可以参考狐狸的思路: @jsp页面创建一个botton bn,该button的 ...

  4. Python常用库大全

    环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具. pyenv – 简单的 Python 版本管理工具. Vex – 可以在虚拟环境中执行命令. v ...

  5. HTML添加样式三种办法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. echarts堆叠图展示,根据数据维度的粒度判断是否展示数据

    1.定义一个参数,返回根据判断什么条件是否显示值; 2.var a = '<%=(String)request.getAttribute("type")%&>' ...

  7. Java异常的性能分析

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt276 在Java中抛异常的性能是非常差的.通常来说,抛一个异常大概会消耗10 ...

  8. distinct和group by 去掉重复数据分析

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp40 用distinct关键字只能过滤查询字段中所有记录相同的(记录集相同) ...

  9. 第1阶段——uboot分析之硬件初始化start.S(4)

    分析uboot第一个执行函数_start(cpu/arm920t/start.S) 打开cpu/arm920t/start.S .globl _start // .globl定义一个全局符号" ...

  10. 【小白成长撸】--顺序栈(C语言版)

    // 顺序栈.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h"//test1.0--栈表仅限Int类型 #include <stdio. ...