CyclicBarrier的使用之王者荣耀打大龙
最近一直整并发这块东西,顺便写点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相当于线程的计数器:
- CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。
- CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。
- CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
CyclicBarrier的使用之王者荣耀打大龙的更多相关文章
- 王者荣耀是怎样炼成的(一)《王者荣耀》用什么开发,游戏入门,unity3D介绍
在国内,如果你没有听说过<王者荣耀>,那你一定是古董级的人物了. <王者荣耀>(以下简称“农药”),专注于移动端(Android.IOS)的MOBA游戏.笔者看到这么火爆,就萌 ...
- Unity 使用 陀螺仪 实现 《王者荣耀》 登入界面 背景动态效果
在 <王者荣耀> 登入界面 左右上下晃动手机(有些手机不支持)可以看到背景在变化 我使用的是iPhone SE 效果如下: 对比两张图片的左下角 可以看到差异 至于为什么要这么做: 1.使 ...
- CNN网络介绍与实践:王者荣耀英雄图片识别
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者介绍:高成才,腾讯Android开发工程师,2016.4月校招加入腾讯,主要负责企鹅电竞推流SDK.企鹅电竞APP的功能开发和技术优化工作 ...
- 浅谈canvas绘画王者荣耀--雷达图
背景: 一日晚上下班的我静静的靠在角落上听着歌,这时"滴!滴!"手机上传来一阵qq消息.原来我人在问王者荣耀的雷达图在页面上如何做出来的,有人回答用canvas绘画.那么问题来了, ...
- 用python的requests第三方模块抓取王者荣耀所有英雄的皮肤
本文使用python的第三方模块requests爬取王者荣耀所有英雄的图片,并将图片按每个英雄为一个目录存入文件夹中,方便用作桌面壁纸 下面时具体的代码,已通过python3.6测试,可以成功运行: ...
- PYTHON-面向对象-练习-王者荣耀 对砍游戏
# 王者荣耀 对砍游戏# 两个英雄可以对砍 如果血量小于等于0 就GG# 所需的对象# 英雄对象""" 亚瑟 属性 类型 血量 名称 技能 Q 跳起来给你一刀 伤害50 ...
- 王者荣耀里拿个王者有啥了不起,有胆就来挑战一下ApsaraCache源码
王者荣耀大家估计都玩的很溜吧,撸完代码开一局,只要不遇到个猪队友,拿个鲁班后羿估计你们都能爆掉对手的塔吧.大神们打个排位赛拿个王者就和吃饭夹菜一样简单... But...你们玩过Redis和Memca ...
- Beta周第14次Scrum会议(11/23)【王者荣耀交流协会】
一.小组信息 队名:王者荣耀交流协会 小组成员 队长:高远博 成员:王超,袁玥,任思佳,王磊,王玉玲,冉华 小组照片 二.开会信息 时间:2017/11/23 17:02~17:14,总计12min. ...
- Beta周第7次Scrum会议(11/16)【王者荣耀交流协会】
一.小组信息 队名:王者荣耀交流协会 小组成员 队长:高远博 成员:王超,袁玥,任思佳,王磊,王玉玲,冉华 小组照片 二.开会信息 时间:2017/11/16 17:03~17:17,总计14min. ...
随机推荐
- Servlet3.1上传图片示例
一.前端JSP页面 <%@page pageEncoding="UTF-8"%><!DOCTYPE html><html><head> ...
- 【LCT】一步步地解释Link-cut Tree
简介 Link-cut Tree,简称LCT. 干什么的?它是树链剖分的升级版,可以看做是动态的树剖. 树剖专攻静态树问题:LCT专攻动态树问题,因为此时的树剖面对动态树问题已经无能为力了(动态树问题 ...
- 部署和使用kibana
背景 上一篇介绍了在阿里云上部署ES,本文将主要介绍ELK的可视化工具Kibana的部署和使用.主要分为三个步骤来实现最终呈现: 1.导入数据到ES: 2.部署kibana并完成配置: 3.使用kib ...
- 推广技巧:新站要如何推广引流做到日IP10000?
一.回复高人气帖子插楼推广 1.找高人气的帖子在二楼或者二楼楼层中直接插入链接推广.虽然这种方法存活率比较低,但也算是贴吧里面最直接的有效的方法.一般我们分为三种: 1.1图中链接是一个短网址,这个是 ...
- poj2901 Hotel
Hotel Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 859 Accepted: 280 Description ...
- python基础教程(八)
创建自已的对象(类)是python非常核心的概念,事实上,python被称为面向对象语言,本章会介绍如何创建对象.以及面向对象的概念:继承.封装.多态. 多态: 可对不同类的对象使用同样的操作. 封装 ...
- FileDetector-基于java开发的照片整理工具
1. 项目背景 开发这个功能的主要原因如下: 1. 大学期间拍摄了约50G的照片,照片很多 2. 存放不规范,导致同一张照片出现在不同的文件夹内,可读性差,无法形成记忆线. 3. 重复存放过多,很多照 ...
- Centos 7系统启动修复
author:JevonWei 版权声明:原创作品 错误界面 这个错误界面应该为/boot文件损坏,故应该修复/boot和grub2 修复/boot及grub 1 . chroot /mnt/sysi ...
- 使用设置sa用户登录sql server2008
今天在net项目中添加数据库过程中出现了小问题,就是使用sql server身份验证没登录成功,经过一番调试,终于解决问题. 使用sa账户登录sql server 2008 的方法步骤如下: 1.首先 ...
- PHP(函数)
<script> // 获得日 var time = new Date(); var x = time.getDate(); document.write(x+"日," ...