文章目录

  • 本章内容 - 多线程处理
    • 绘制敌方坦克
  • 线程基础
    • 线程相关概念
      • 程序(program)
      • 进程
      • 什么是线程
      • 其他相关概念
        • 单线程
        • 多线程
        • 并发
        • 并行
        • 获取当前电脑处理器(cpu)个数
      • Java中创建线程的两种方式
  • 线程基本使用(重要)
    • 案例1
      • 使用JConsole监控器
    • 为什么使用start()方法(重点)
    • 案例2
      • 实现Runnable接口
      • 设计模式(代理模式)
    • 线程作业练习
    • 继承Thread 和 实现Runnable的区别
      • 案例演示
    • 注意

本章内容 - 多线程处理

绘制敌方坦克

  1. 因为敌人的坦克,是在MyPanel上,所以我们的代码在MyPanel
  2. 因为敌人的坦克,后面有自己的特殊的属性和方法,可以单开一个EnemyTank
  3. 敌人坦克数量多,可以放入到集合Vector(多线程安全性)
  • 新建EnemyTank类继承Tank类,构造方法传入x,y
public class EnemyTank extends Tank {public EnemyTank(int x, int y){super(x,y);}}
  • 创建集合,遍历并初始化坦克位置
    //定义我的坦克Hero hero = null;//定义敌人坦克,放入到Vector集合Vector<EnemyTank> enemyTanks = new Vector();int enemyTanksSize = 3;public MyPanel(){hero = new Hero(500,500);   //初始化自己的坦克hero.setSpeed(50);               //初始化坦克速度//初始化敌人坦克for (int i = 0; i < enemyTanksSize; i++) {enemyTanks.add(new EnemyTank(100 + i * 100,100));}}
  • paint方法中,for循环画出敌方坦克
    public void paint(Graphics g){super.paint(g);g.fillRect(0,0,1000,750);    //填充矩形,默认黑色//画出坦克 - 封装方法//自己的坦克drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),1);        //type坦克类型//敌人的坦克for (int i = 0; i < enemyTanks.size(); i++) {//取出坦克EnemyTank enemyTank = enemyTanks.get(i);drawTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),0);}}
  • 地方坦克炮筒向下
        for (int i = 0; i < enemyTanks.size(); i++) {//取出坦克EnemyTank enemyTank = enemyTanks.get(i);enemyTank.setDirect(2); //默认向下drawTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),0);}

线程基础

线程相关概念

程序(program)

是为完成特定任务、用某种语言编写的一组指令的集合。

简单的说:就是我们写的代码

进程

  1. 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间。当我们使用迅雷,又启动了一个进程,操作系统将为迅雷分配新的内存空间。
  2. 进程是程序的一次执行过程,或是正在运行的一个程序。是动态过程:有它自身的产生,存在和消亡的过程

什么是线程

  1. 线程由进程创建的,是进程的一个实体
  2. 一个进程可以拥有多个线程,如下图(emm,大概就是这个意思叭~~)

其他相关概念

单线程

同一时刻,只允许执行一个线程

多线程

同一时刻,可以执行多个线程,比如:一个qq进程,可以同时打开多个聊天窗口,一个迅雷进程,可以同时下载多个文件

并发

同一个时刻,多个任务交替执行,造成一种“貌似同时”的错觉,简单的说,单核cpu实现的多任务就是并发

并行

同一个时刻,多个任务同时执行。多核cpu可以实现并行。

获取当前电脑处理器(cpu)个数

Runtime类

/*** Create By 刘鸿涛* 2022/1/14 2:51*/
public class CupNum {public static void main(String[] args) {Runtime runtime = Runtime.getRuntime();//Processors :处理器int cupNums = runtime.availableProcessors();System.out.println("我的电脑的cpu个数为:" + cupNums);}
}

Java中创建线程的两种方式

  1. 继承Thread类,重写run方法
  2. 实现Runnable接口,重写run方法

线程基本使用(重要)

案例1

  1. 编写程序,开启一个线程,该线程每隔1秒,在控制台输出“喵喵,我是小喵咪”
  2. 对上题改进:当输出80次“喵喵,我是小喵咪”,结束该线程
  3. 使用JConsole监控线程执行情况,并画出程序示意图
package com.tao.threaduse;/*** Create By 刘鸿涛* 2022/1/14 3:07*/
public class Thread01 {public static void main(String[] args) throws InterruptedException {Cat cat = new Cat();//启动线程cat.start();    //Thread类方法,实现Tunnable则无次方法//说明:当main线程启动一个子线程Thread-0,主线程不会阻塞,会继续执行System.out.println("主线程继续执行" + Thread.currentThread().getName());   //main线程for (int i = 0; i < 35; i++) {System.out.println("主线程" + i);if(i == 34){System.out.println("主线程已死");}//让主线程休眠Thread.sleep(1000);}}
}//1.当一个类继承了 Thread 类,该类就可以当作线程使用
//2.我们会重写 run 方法,写上自己的业务代码
//3.run Thread 类 实现了 Tunnable 接口的 run方法
class Cat extends Thread{      //implements Tunnable@Overridepublic void run() {     //重写run方法int count = 0;while (true){try{Thread.sleep(1000);     //程序休眠1000毫秒}catch(InterruptedException e){e.printStackTrace();}System.out.println("喵喵,我是小喵咪" + Thread.currentThread().getName());  //打印线程名字count++;if(count == 40){break;}}}
}

  • 理论上可以更复杂些,比如下面这样

使用JConsole监控器

  • 注意,需要程序运行时使用查找线程功能

为什么使用start()方法(重点)

  • 因为你在main方法中调用run()方法后,你的线程名,依然是main,依然是单线程

  • start()方法调用start0()方法后,该线程并不一定会立马执行,只是将线程变成了可运行状态,具体什么时候执行,取决于CPU,由CPU统一调度

案例2

实现Runnable接口

  1. java是单继承的,在某些情况下一个类可能已经继承了某个父类,这时在用继承Thread类方法来创建线程显然不可能了
  2. java设计者们提供了另外一个方式创建线程,就是通过实现Runnable接口来创建线程
 package com.tao.threaduse;/*** Create By 刘鸿涛* 2022/1/15 1:37*/
public class Thread02 {public static void main(String[] args) {Dog dog = new Dog();//Runnable接口没有start()方法
//        dog.start();//实现思路//创建Thread对象,把 dog对象(实现Runnable),放入Thread类//这里用了设计模式中- 《代理模式》Thread thread = new Thread(dog);thread.start();}
}
class Dog implements Runnable{@Overridepublic void run() {int count = 0;while(true){System.out.println("小狗汪汪第" + (++count) + "次叫" + Thread.currentThread().getName());try{Thread.sleep(1000);}catch(InterruptedException e){e.printStackTrace();}if (count > 5){break;}}}
}

设计模式(代理模式)

  • 我这个类没有这个方法,但是我可以请代理类帮我完成这个方法,但实际上工作的还是原来的类方法
package com.tao.threaduse;/*** Create By 刘鸿涛* 2022/1/15 1:53*/
public class Thread03 {public static void main(String[] args) {Tiger tiger = new Tiger();  //实现了Runnable接口Proxy proxy = new Proxy(tiger);//因为Tiger、Proxy都实现了Runnable接口proxy.start();}
}
class Animal{}
class Tiger extends Animal implements Runnable{@Overridepublic void run() {System.out.println("老虎嗷嗷叫..." + Thread.currentThread().getName());  //main线程}
}
//Proxy:代理
//线程代理类,模拟了一个极简的Thread类
class Proxy implements Runnable{    //你可以把Proxy类当作 Thread,private Runnable target = null; //属性,类型是 Runnable@Overridepublic void run() {if (target != null){target.run();           //动态绑定(运行类型Tiger)}}public Proxy(Runnable target){  //target = tigerthis.target = target;}public void start(){start0();   //这个方法真正实现多线程}public void start0(){run();}
}

线程作业练习

package com.tao.threaduse;/*** Create By 刘鸿涛* 2022/1/15 2:22*/
public class Homework01 {public static void main(String[] args) {Thread01_ thread01_ = new Thread01_();Thread thread =  new Thread(thread01_);thread.start(); //线程1 - Thread-0Thread02_ thread02_ = new Thread02_();thread02_.start();}
}
class Thread01_ implements Runnable{@Overridepublic void run() {int count = 0;while(true){System.out.println("第" + ++count + "helloword" + Thread.currentThread().getName());try{Thread.sleep(1000);}catch(InterruptedException e){}if (count == 10){break;}}}
}
class Thread02_ extends Thread{@Overridepublic void run(){int count = 0;while(true){System.out.println("第" + ++count + "hi" + Thread.currentThread().getName());try{Thread.sleep(1000);}catch(InterruptedException e){e.printStackTrace();}if (count == 5){break;}}}
}

继承Thread 和 实现Runnable的区别

  1. 从java的设计来看,通过继承Thread或者实现Runnable接口来创建线程本质上没有区别,从jdk帮助文档我们可以看到Thread类本身就实现了Runnable接口
  2. 实现Runnable接口方式更加适合多个线程共享一个资源的情况,并且避免了单继承的限制
  3. 建议使用Runnable接口

案例演示

  • [售票系统],编程模拟三个售票窗口售票100,分别使用 继承 Thread 和实现Runnable方式,并分析有什么问题?
package com.tao.threaduse;/*** Create By 刘鸿涛* 2022/1/15 4:45*/
public class Homework02 {public static void main(String[] args) {//继承Thread
//        SellTicket01 sellTicket01 = new SellTicket01();
//        SellTicket01 sellTicket02 = new SellTicket01();
//        SellTicket01 sellTicket03 = new SellTicket01();
//        sellTicket01.start();   //启动售票线程
//        sellTicket02.start();   //启动售票线程
//        sellTicket03.start();   //启动售票线程//实现Runnable接口
//        SellTicket02 sellTicket02 = new SellTicket02();
//        SellTicket02 sellTicket021 = new SellTicket02();
//        SellTicket02 sellTicket022 = new SellTicket02();
//        Thread thread = new Thread(sellTicket02);
//        Thread thread1 = new Thread(sellTicket021);
//        Thread thread2 = new Thread(sellTicket022);
//        thread.start();
//        thread1.start();
//        thread2.start();SellTicket02 sellTicket02 = new SellTicket02();new Thread(sellTicket02).start();new Thread(sellTicket02).start();new Thread(sellTicket02).start();}
}
class SellTicket01 extends Thread{private static int ticketNum = 100; //@Overridepublic void run(){while(true){if(ticketNum <= 0){System.out.println("售票结束");break;}try{Thread.sleep(50);}catch(InterruptedException e){e.printStackTrace();}System.out.println("窗口 " + Thread.currentThread().getName() +"卖出了一张票" + "\n剩余票数:" + (--ticketNum));}}
}
class SellTicket02 implements Runnable{private static int ticketNum = 100; //@Overridepublic void run(){while(true){if(ticketNum <= 0){System.out.println("售票结束");break;}try{Thread.sleep(50);}catch(InterruptedException e){e.printStackTrace();}System.out.println("窗口 " + Thread.currentThread().getName() +"卖出了一张票" + "\n剩余票数:" + (--ticketNum));}}
}

  • 不管是继承Thread还是实现Runnable接口,都会出现超卖现象

注意

  • main线程可以比其他线程先死!

Java基础 - 坦克大战(第三章,线程基础与线程使用)相关推荐

  1. JAVA之坦克大战(三)我方坦克发射炮弹

    思路:添加子弹类,并且写出子弹运行的线,然后在Mytank中添加新的fire()方法,用于发射子弹时获得当前炮管的方向,因为子弹较多所以需要把子弹放在Vector集合里,并且需要开多线程,因为子弹运动 ...

  2. java坦克大战登录界面设计_基于JAVA的坦克大战设计和实现-代码.doc

    JISHOU UNIVERSITY 本科生毕业设计 题 目:基于JAVA的坦克大战设计与实现作 者:学 号:所属学院:专业年级:指导教师:职 称:完成时间:2012年5月7日 吉首大学 基于JAVA的 ...

  3. Java版坦克大战游戏

    技术:Java等 摘要: Java随着各种电子设备,其中尤其是移动通信设备的发展所诞生的一项新的开发技术.Java定位在各种电子设备产品的功能应用上,对电子产品的多样,智能化,提供了很大的帮助.本次设 ...

  4. 软考 程序员教程-第三章 数据库基础知识

    软考 程序员教程-第三章 数据库基础知识 第三章 数据库基础知识 3.1 基本概念 数据库系统(DataBase System,DBS)由数据库(DataBase,DB).硬件.软件和人员4大部分组成 ...

  5. java小组坦克大战游戏开发文档开发日志_java实现坦克大战游戏

    本文实例为大家分享了java实现坦克大战游戏的具体代码,供大家参考,具体内容如下 一.实现的功能 1.游戏玩法介绍 2.自定义游戏(选择游戏难度.关卡等) 3.自定义玩家姓名 4.数据的动态显示 二. ...

  6. Java实现坦克大战,单机版和联网版

    Java实现坦克大战 源码获取途径 部分源代码 源码获取途径 百度网盘链接: 百度网盘地址 提取码:5r7i GitHub Github获取地址 部分源代码 public class TankClie ...

  7. 【JAVA程序设计】基于JAVA的坦克大战小游戏--入门级小游戏

    基于JAVA的坦克大战小游戏--入门级小游戏 零.项目获取 一.项目简介 二.开发环境 三.游戏玩法 四.运行截图 零.项目获取 获取方式(点击下载):是云猿实战 项目经过多人测试运行,可以确保100 ...

  8. java怎么连发子弹_【Java_项目篇1】--JAVA实现坦克大战游戏--子弹连发+爆炸效果(四)...

    前期相关文章 [Java_项目篇<1>]–JAVA实现坦克大战游戏–画出坦克(一) [Java_项目篇<1>]–JAVA实现坦克大战游戏–坦克移动+添加敌方坦克(二) [Jav ...

  9. 【Java_项目篇1】--JAVA实现坦克大战游戏--坦克移动+添加敌方坦克(二)

    前期文章: [Java_项目篇<1>]--JAVA实现坦克大战游戏--画出坦克(一) 控制小球移动 1.外部类 实现KeyListener监听接口写法 package com.test3; ...

  10. 第三章网络安全基础考试要点及真题分布

    第三章网络安全基础 1.计算机网络基本知识 2.网络安全的基本概念 3.网络安全威胁 4.网络安全防御 5.无线网络安全

最新文章

  1. ios签名软件_如何给无法上架App Store的App做ios签名?
  2. Nature:FB和推特的数据是如何革新社会科学,改变世界的?
  3. python怎么样才算入门编程-新手如何入门Python编程
  4. php 挂机,用php实现qq挂机
  5. HDU 2859 Phalanx (dp)
  6. JVM从入门到精通(九):JVM调优实战 - arthas 的使用
  7. oracle 误删表空间文件启动不了数据库的解决办法
  8. 每次请求刷新token的时间
  9. MTK 驱动(73)--- Kernel Backtrace 无法显示出具体的地址.
  10. hibernate之自定义持久化实现
  11. python 获取当前路径_Python获取当前路径实现代码
  12. 【语言学习】Java
  13. 输入姓名自动生成拼音
  14. Unity中录制VR全景视频(可录制UGUI)
  15. 天龙八部服务器维护几点开服,天龙八部开服时间表2020-开服时间表一览
  16. nginx完全卸载删除
  17. ORACLE一次大量数据删除导致问题的处理
  18. mac安装php的mongodb扩展报错:No such file or directory autom4te: /usr/bin/m4 failed with exit status: 1...
  19. ArcGIS教程:了解欧氏距离分析
  20. k8s学习(二十) helm的基本使用

热门文章

  1. 妇与术(二):女性营销频频翻车?搞懂“女性凝视”太太太有必要了!
  2. yum源配置,亲测可用
  3. Java0921练习
  4. 金山打字通2008下载-金山打字通2008正式版-金山打字通2008完整版
  5. ADKEY多按键制作阻值选择
  6. 杰理之 U盘、T卡顺序切换【篇】
  7. HMM经典介绍论文【Rabiner 1989】翻译(一)——介绍
  8. 关于iOS的自动化测试
  9. 数据复盘 Phanta Bear和TheHeart Project:亚洲名人项目正席卷 NFT 市场
  10. QT 程序自适应屏幕分辨率