用JAVA多线程实现龟兔赛跑
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用JAVA多线程实现龟兔赛跑相关的知识,希望对你有一定的参考价值。
创建两个线程,实现龟兔赛跑,线程每次执行休眠500毫秒,两个线程每次分别执行乌龟前行10米与兔子前行10米。一方先到100米处结束程序,显示获胜信息。
本人初学,请用大家写的简单易懂一点,谢谢!!
分不够多,请大家帮帮忙!!
/**
*
* GuiTuSaiPao.java
* @author Antonio
* 2009年9月2日20:16:33
* 实现Runnable接口中的run方法
*
*/
public class GuiTuSaiPao implements Runnable
private String name;
private int length=0;
public GuiTuSaiPao()
public GuiTuSaiPao(String name)
this.name=name;
public void run()
while(true)
//每次停500毫秒
try
Thread.sleep(500);
catch (InterruptedException e)
e.printStackTrace();
//向前跑十米
length+=10;
System.out.println(name+"已跑了"+length+"米.");
//到达终点
if(length>=100)
System.out.println(name+",已经到达终点!");
//结束赛跑,break
break;
public static void main(String[] args)
GuiTuSaiPao wugui=new GuiTuSaiPao("乌龟");
GuiTuSaiPao tuzi=new GuiTuSaiPao("兔子");
Thread thread=new Thread(wugui);
Thread thread2=new Thread(tuzi);
//启动线程
thread.start();
thread2.start();
输出结果:(不一定每次都一样!)
乌龟已跑了10米.
兔子已跑了10米.
兔子已跑了20米.
乌龟已跑了20米.
乌龟已跑了30米.
兔子已跑了30米.
兔子已跑了40米.
乌龟已跑了40米.
兔子已跑了50米.
乌龟已跑了50米.
乌龟已跑了60米.
兔子已跑了60米.
乌龟已跑了70米.
兔子已跑了70米.
乌龟已跑了80米.
兔子已跑了80米.
兔子已跑了90米.
乌龟已跑了90米.
兔子已跑了100米.
兔子,已经到达终点!
乌龟已跑了100米.
乌龟,已经到达终点!
完全看rp,这就是线程!
给分吧,哈哈本回答被提问者采纳 参考技术B package test;
public class RunningGame
public static void main(String[] args)
Runner wugui = new Runner("wugui");
Runner tuzi = new Runner("tuzi");
//为增加趣味性,可用重载的构造函数,初始化各项数据,这样兔子睡觉时间比较多,但速度比较快,胜负难料
// Runner wugui = new Runner("wugui",500,10);
// Runner tuzi = new Runner("tuzi",1200,25);
wugui.start();
tuzi.start();
class Runner extends Thread
private static final int LENGTH = 100; //总路程
private String name; //名字
private int sleep = 500; //睡觉时间
private int speed = 10; //速度
private int meter = 0; //当前路程
public Runner(String name)
this.name = name;
public Runner(String name, int sleep)
this.name = name;
this.sleep = sleep;
public Runner(String name, int sleep, int speed)
this.name = name;
this.sleep = sleep;
this.speed = speed;
public void run()
while(meter < LENGTH)
try
Thread.sleep(sleep);
catch (InterruptedException e)
e.printStackTrace();
meter += speed;
System.out.println(name+":" + meter + " meters");
System.out.println(name + " win the game");
System.exit(0);
参考技术C 兄弟??
还要写个程序给你??
最多是给你点提示罢了....
狂神说Java笔记--多线程详解部分笔记
传送门==>B站遇见狂神说Java多线程详解
做笔记时有的知识点并没有整理;
ml
1.线程创建之继承Thread类
- 首先自定义线程类继承Thread类;
- 然后是重写run( )方法;编写线程执行体
- 然后创建自定义线程对象;使用start()方法启动线程
注意:
线程开启并不一定是直接就执行;得看CPU的调度,或者说的根据CPU的实际资源情况
;
代码练习:
创建MyThread
/**
* 线程创建之继承Thread类;
*/
//1.首先继承Thread类;
public class MyThread01 extends Thread {
//2.然后是重写run方法;编写执行的线程;
@Override
public void run() {
//run方法 线程的执行体;
for (int i = 0; i < 100; i++) {
System.out.println("我是run方法->"+i);
}
}
//mian方法;(主线程)
public static void main(String[] args) {
//创建线程对象;
MyThread01 myThread01=new MyThread01();
//3.使用start方法启动线程;
myThread01.start();
//main方法 线程的执行体;
for (int i = 0; i < 100; i++) {
System.out.println("我是main方法->"+i);
}
}
}
线程交替执行
而如果不使用start方法启动线程呢;直接在main方法中调用run方法;那就按着方法的调用顺序执行了,依次有序地执行
图片下载练习
//继承Thread类;
public class MyThread02 extends Thread{
//定义网页地址和文件名;
private String url;
private String name;
//构造方法;初始化;
public MyThread02(String url, String name) {
this.url = url;
this.name = name;
}
//重写run方法
@Override
public void run() {
//创建下载器对象;
WebDownLoader wdl=new WebDownLoader();
//调用下载方法;
wdl.dowLoade(url,name);
System.out.println("下载文件名=>"+name);
}
//主方法;
public static void main(String[] args) {
MyThread02 myT1=new MyThread02("https://www.baidu.com/link?url=dvRgPF9UDWw42jQF0lr8EnKMw2XfU_NKhWqanB4wL85sqwWrGBVnBAGd3zBJUJ0JZa0d3ryBEd6FCiZfrG1ax0o3EkygROiBPwUrzEFRoC4DK6S5DSiMz1Q1Ge_O8vyNbE8IzW1Kn2WGbHDgGzx4yhlQsOadV1rFqemy4Os4lhBMAxGLXZ2CY5ftLFMYzxUgZbFIw5qtkPUajas-nPD4yyk118flZrp6Dj6HOAfwKB-X0xbxH2ttXMocCGzVHuwGm0a0Orw8A_cqyOm3tDvXMhKu3YSYHtKDkisZqupVBI3pJhhvP97RCXacC0jtynAXvUrPz4OAhT_QvMfWp7akjFP5gBFiK_5Tt2BwRchJ1YgenbZwqGucGAopjBtmlKeAKOmkaVJ12wiG6u7Y85YNIlGo__O0ZgurYtRb4WbOZTxsBX_e0XrBB0klH2V2BJM3YuEyMpc_6sZdwhYnj4JCltSh1oca5jDlQ51Tu2LHqI-SeDhvi_ioBAno4NzkQqEI_rhRIJSUqb7EVBjO7sTEB8qohgcbM9ZtD-3fqTYTRZBQ97W0o5p2tUTEVuXDTM0FeunmEEoiaLeBCSJbB8to09OYCCy9C-e2CZyaaiIAnXvAlAILYMaHh0a1ANXLzFR1&wd=&eqid=9a0261300016198200000005611d721a","图1.jpg");
MyThread02 myT2=new MyThread02("https://www.baidu.com/link?url=dvRgPF9UDWw42jQF0lr8EnKMw2XfU_NKhWqanB4wL85sqwWrGBVnBAGd3zBJUJ0JZa0d3ryBEd6FCiZfrG1ax0o3EkygROiBPwUrzEFRoC4DK6S5DSiMz1Q1Ge_O8vyNbE8IzW1Kn2WGbHDgGzx4yhlQsOadV1rFqemy4Os4lhBMAxGLXZ2CY5ftLFMYzxUgZbFIw5qtkPUajas-nPD4yyk118flZrp6Dj6HOAfwKB-X0xbxH2ttXMocCGzVHuwGm0a0Orw8A_cqyOm3tDvXMhKu3YSYHtKDkisZqupVBI3pJhhvP97RCXacC0jtynAXvUrPz4OAhT_QvMfWp7akjFP5gBFiK_5Tt2BwRchJ1YgenbZwqGucGAopjBtmlKeAKOmkaVJ12wiG6u7Y85YNIlGo__O0ZgurYtRb4WbOZTxsBX_e0XrBB0klH2V2BJM3YuEyMpc_6sZdwhYnj4JCltSh1oca5jDlQ51Tu2LHqI-SeDhvi_ioBAno4NzkQqEI_rhRIJSUqb7EVBjO7sTEB8qohgcbM9ZtD-3fqTYTRZBQ97W0o5p2tUTEVuXDTM0FeunmEEoiaLeBCSJbB8to09OYCCy9C-e2CZyaaiIAnXvAlAILYMaHh0a1ANXLzFR1&wd=&eqid=9a0261300016198200000005611d721a","图2.jpg");
MyThread02 myT3=new MyThread02("https://www.baidu.com/link?url=dvRgPF9UDWw42jQF0lr8EnKMw2XfU_NKhWqanB4wL85sqwWrGBVnBAGd3zBJUJ0JZa0d3ryBEd6FCiZfrG1ax0o3EkygROiBPwUrzEFRoC4DK6S5DSiMz1Q1Ge_O8vyNbE8IzW1Kn2WGbHDgGzx4yhlQsOadV1rFqemy4Os4lhBMAxGLXZ2CY5ftLFMYzxUgZbFIw5qtkPUajas-nPD4yyk118flZrp6Dj6HOAfwKB-X0xbxH2ttXMocCGzVHuwGm0a0Orw8A_cqyOm3tDvXMhKu3YSYHtKDkisZqupVBI3pJhhvP97RCXacC0jtynAXvUrPz4OAhT_QvMfWp7akjFP5gBFiK_5Tt2BwRchJ1YgenbZwqGucGAopjBtmlKeAKOmkaVJ12wiG6u7Y85YNIlGo__O0ZgurYtRb4WbOZTxsBX_e0XrBB0klH2V2BJM3YuEyMpc_6sZdwhYnj4JCltSh1oca5jDlQ51Tu2LHqI-SeDhvi_ioBAno4NzkQqEI_rhRIJSUqb7EVBjO7sTEB8qohgcbM9ZtD-3fqTYTRZBQ97W0o5p2tUTEVuXDTM0FeunmEEoiaLeBCSJbB8to09OYCCy9C-e2CZyaaiIAnXvAlAILYMaHh0a1ANXLzFR1&wd=&eqid=9a0261300016198200000005611d721a","图3.jpg");
//启动线程;
myT1.start();
myT2.start();
myT3.start();
}
}
//创建下载器;
class WebDownLoader{
//下载方法;
public void dowLoade(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("下载方法有问题, IO异常");
}
}
}
运行;下载时并不会按照顺序,
2.线程创建之实现Runnable接口
可避免单继承的局限性;方便一个对象被多个线程使用.
- 自定义类实现Runnable接口;
- 重写run()方法,编写线程执行体
- 创建自定义线程对象放入Thread对象中,start()方法启动线程
代码练习
/**
* 创建线程之实现Runnable接口
*/
//实现Runnable接口;
public class MyThread03 implements Runnable {
//重写run方法;
@Override
public void run() {
//run方法 线程的执行体;
for (int i = 0; i < 100; i++) {
System.out.println("我是run方法->" + i);
}
}
//主方法;
public static void main(String[] args) {
//创建实现类的对象;
MyThread03 myThread03 = new MyThread03();
//创建线程对象;启动线程
new Thread(myThread03).start();
//main方法 线程的执行体;
for (int i = 0; i < 100; i++) {
System.out.println("我是main方法->" + i);
}
}
}
买票案例
多个线程去操作同一份资源,线程不安全
//实现Runnable接口;
public class MyThreadToTicket implements Runnable {
//定义车票数量;
private int ticket=10;
//重写run方法;
@Override
public void run() {
while(true) {
//票买完就停了;
if(ticket<=0) {
break;
}
try {
//定义延时;
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Thread.currentThread().getName():可获取到当前线程的名字;
System.out.println(Thread.currentThread().getName() + "::买到了第" + ticket-- + "个票");
}
}
//主方法;
public static void main(String[] args) {
//创建自定义类的对象;
MyThreadToTicket mt=new MyThreadToTicket();
//创建Thread对象,启动线程;
new Thread(mt,"阿杰").start();
new Thread(mt,"阿猫").start();
new Thread(mt,"阿伟").start();
}
}
运行时,出现两个人买到同一张票的问题.
模拟龟兔赛跑
//实现Runnable接口;
public class TorAndRabRun implements Runnable {
//定义胜利者;
private static String win;
//判断是否结束比赛; step:步数;
private boolean over(int step){
//若已有获胜者,则结束;
if(win!=null){
return true;
}{
//若已经跑完了,结束比赛;
if(step>=100){
win=Thread.currentThread().getName();
System.out.println("获胜者" + win);
return true;
}
}
return false;
}
//重写run方法
@Override
public void run() {
for (int i = 0; i <= 101; i++) {
//模拟兔子睡觉;
if(Thread.currentThread().getName().equals("兔纸")&&i%10==0){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//若比赛结束,终止循环;
if (over(i)) {
break;
}
//Thread.currentThread().getName():会获取线程名;
System.out.println(Thread.currentThread().getName()+"==>跑"+i+"米");
}
}
//主方法;
public static void main(String[] args) {
//创建赛道对象;
TorAndRabRun tar=new TorAndRabRun();
//创建线程对象,启动线程;
new Thread(tar,"乌龟").start();
new Thread(tar,"兔纸").start();
}
}
3.线程创建之实现Callable接口
- 实现callable接口,需要返回值类型;
- 重写call方法;需要抛出异常类型;
- 创建自定义线程的对象;
- 开启服务;
- 提交执行;
- 获取结果;
- 关闭服务
使用之前的多线程下载图片案例;
/**
* 线程创建之实现Callable接口;和前两种不同的是该方式可产生返回值;
*/
//实现Callable接口;
public class MyThread04 implements Callable<Boolean> {
//定义网页地址和文件名;
private String url;
private String name;
//构造方法;初始化;
public MyThread04(String url, String name) {
this.url = url;
this.name = name;
}
//重写callable方法;
@Override
public Boolean call() throws Exception {
//创建下载器对象;
WebDownLoader wdl=new WebDownLoader();
//调用下载方法;
wdl.dowLoade(url,name);
System.out.println("下载文件名=>"+name);
return null;
}
//主方法
public static void main(String[] args) throws ExecutionException, InterruptedException{
//创建实现类的对象;
MyThread04 myT1=new MyThread04("https://img-blog.csdnimg.cn/20210613214620230.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01yVHVtbnVz,size_16,color_FFFFFF,t_70","图片1.png");
MyThread04 myT2=new MyThread04("https://img-blog.csdnimg.cn/20210613214620230.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01yVHVtbnVz,size_16,color_FFFFFF,t_70","图片2.png");
MyThread04 myT3=new MyThread04("https://img-blog.csdnimg.cn/20210613214620230.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01yVHVtbnVz,size_16,color_FFFFFF,t_70","图片3.png");
//开启服务;(创建线程池)
ExecutorService es= Executors.newFixedThreadPool(3);
//执行服务提交;
Future<Boolean> ft1=es.submit(myT1);
Future<Boolean> ft2=es.submit(myT2);
Future<Boolean> ft3=es.submit(myT3);
//获取返回结果;
Boolean res1 = ft1.get();
Boolean res2 = ft2.get();
Boolean res3 = ft3.get();
System.out.print(res1);
System.out.print(res2);
System.out.print(res3);
//关闭服务;
es.shutdownNow();
}
}
//创建下载器;
class WebDownLoader{
//下载方法;
public void dowLoade(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("下载方法有问题, IO异常");
}
}
}
也是交替执行的;
4.静态代理模式
- 真实对象(目标对象)和代理对象都要实现同一个接口;
- 代理对象要代理真实角色;
- 代理对象可实现真实对象不能完成的方法;
- 真实对象专注自己的实现;
public class StaticProxy {
public static void main(String[] args) {
//代理 | 真实 | 需要完成的事情;
//new Thread(()->System.out.println("完成")).start();
/* //创建真实角色对象;
Person ps=new Person();
//创建代理角色对象;
ProxyPerson prop=new ProxyPerson(ps);
prop.Happy();*/
//实际上,可精简为;
// 代理 | 真实 | 需要完成的事情;
new ProxyPerson(new Person()).Happy();
}
}
//接口;
interface Marry{
//抽象方法;
void Happy();
}
//人;(真实角色)
class Person implements Marry{
@Override
public void Happy() {
System.out.println("真实角色出场");
}
}
//中介;(代理角色)
class ProxyPerson implements Marry{
//定义目标对象1;
private Marry targetP;
//构造方法;
public ProxyPerson(Marry targetP) {
this.targetP = targetP;
}
@Override
public void Happy() {
//调用之前要完成的方法;
brfore();
//执行方法;
this.targetP.Happy();
//调用之后要完成的方法
after();
}
//之前要进行的方法;
private void brfore() {
System.out.println("前面要完成的事情;");
}
//之后要进行的方法;
private void after() {
System.out.println("后面要完成的事情;");
}
}
5.Lambda表达式
lambda:
λ:希腊字母表第11位;
使用目的是为了避免匿名内部类定义过多;实质上属于函数式编程;
-----------------------------------
(params)->expression [表达式]
(params)->statement (语句)
-----------------------------------
函数式接口:(Functional Interface)
----------------------------------
函数式接口定义:
只包含唯一的抽象方法;
可使用lambda表达式创建接口对象
练习;使用不同的方式实现输出接口方法;
public class DemoLamDa01 {
//2.使用静态内部类;
static class FunImpl02 implements FunMeth{
@Override
public void OnlyMethod以上是关于用JAVA多线程实现龟兔赛跑的主要内容,如果未能解决你的问题,请参考以下文章