• 创建多线程


    多线程概念


      进程:当点开英雄联盟的时候,我们就启动了一个进程。如果这时候又打开QQ音乐,那我们就是又开启了一个进程。

      线程:线程是进程内部同时在做的事情,比如在英雄联盟游戏中,"盖伦正在击杀提莫",同一时刻"赏金猎人又在击杀盲僧",这个时候盖伦击杀提莫这件事就是一个线程,在这里两个线程在做事情,就统称多线程。

    顺序执行线程


       1、描述两件事情,并没有同时发生,只是一件事情发生完了以后,另一件事情才开始。Hero类

    package com.thread;
    
    public class Hero {
        public String name;
        public float hp;
    
        public int damage;
    
        public void attackHero(Hero h) {
            try {
                //为了表示攻击需要时间   每次攻击暂停1秒
                Thread.sleep(1000);
            }catch(InterruptedException e) {
                e.printStackTrace();
            }
            h.hp -= damage;
            System.out.format("%s 正在攻击 %s, %s的血变成了 %.0f%n", name, h.name, h.name, h.hp);
            if(h.isDead()) {
                System.out.println(h.name + "死了!");
            }
        }
    
        //判断英雄死了没
        public boolean isDead() {
            return 0 >= hp?true:false;   //血量大于0  没死   isDead=false
        }
    }

      2、顺序执行两个模拟的线程,TestThread

    package com.thread;
    
    public class TestThread {
        public static void main(String[] args) {
            Hero gareen = new Hero();
            gareen.name = "盖伦";
            gareen.hp = 616;
            gareen.damage = 50;
    
            Hero teemo = new Hero();
            teemo.name = "提莫";
            teemo.hp = 300;
            teemo.damage = 30;
    
            Hero bh = new Hero();
            bh.name = "赏金猎人";
            bh.hp = 500;
            bh.damage = 65;
    
            Hero leesin = new Hero();
            leesin.name = "盲僧";
            leesin.hp = 445;
            leesin.damage = 80;
    
            //盖伦攻击提莫
            while(!teemo.isDead()) { //提莫的是否死亡   false就是没死   !false=true      那么盖伦继续攻击 直到提莫没了
                gareen.attackHero(teemo);   //盖伦攻击提莫
            }
    
            //赏金猎人攻击盲僧
            while(!leesin.isDead()) {
                bh.attackHero(leesin);  //赏金猎人攻击盲僧
            }
        }
    }

      效果

     创建线程


       三种方式:继承Thread类,实现Runnable接口,内部类

      1、继承Thread类。Thread类实现了Runnable接口,这里run方法重写了Runnable中的run方法,重新定义算法,这个算法描述此线程在做什么事情。

    package com.thread.thread1;
    
    import com.thread.Hero;
    
    //这里继承Thread   Thread本质也是实现Runnable接口    THread重写run方法
    public class KillThread extends Thread {
        private Hero h1;  //做两个英雄出来
        private Hero h2;
    
        public KillThread(Hero h1, Hero h2) {  //把两个英雄放入killTHread中
            this.h1 = h1;
            this.h2 = h2;
        }
    
        public void run() {   //这里继承 重新声明了run方法 没有用原本的
            while(!h2.isDead()) {
                h1.attackHero(h2);
            }
        }
    }

      启动线程测试,这里传入的对象作为参数,传递到线程类中的构造方法,实例出来的线程对象,调用其父类Thread的start方法,执行该线程的run函数。

    package com.thread.thread1;
    import com.thread.Hero;
    public class TestT {
        public static void main(String[] args) {
    
            Hero gareen = new Hero();
            gareen.name = "盖伦";
            gareen.hp = 616;
            gareen.damage = 50;
    
            Hero teemo = new Hero();
            teemo.name = "提莫";
            teemo.hp = 300;
            teemo.damage = 30;
    
            Hero bh = new Hero();
            bh.name = "赏金猎人";
            bh.hp = 500;
            bh.damage = 65;
    
            Hero leesin = new Hero();
            leesin.name = "盲僧";
            leesin.hp = 455;
            leesin.damage = 80;
    
            //创建一个线程  里面盖伦和提莫在打架
            KillThread killThread1 = new KillThread(gareen, teemo);
            killThread1.start();   //启动线程  执行Thread中start方法   我们自己声明的线程类没有这个start方法
    
    
            KillThread killThread2 = new KillThread(bh, leesin);   //再创建一个线程
            killThread2.start();   //第二个线程启动
    
            //总结 两个线程互不影响
        }
    }

      2、实现Runnable接口,实现接口,实现的是接口内的方式,override。

    package com.thread.thread2;
    import com.thread.Hero;
    public class Battle implements Runnable{
    
        private Hero h1;
        private Hero h2;
    
        public Battle(Hero h1, Hero h2) {
            this.h1 = h1;
            this.h2 = h2;
        }
    
        @Override
        public void run() {
            while(!h2.isDead()) {
                h1.attackHero(h2);
            }
        }
    }

      编写测试类,重新new了一个线程,将自己实现的类的实例对象传入线程中,然后启动线程的start方法

    package com.thread.thread2;
    
    import com.thread.Hero;
    
    public class TestT {
        public static void main(String[] args) {
            Hero gareen = new Hero();
            gareen.name = "盖伦";
            gareen.hp = 616;
            gareen.damage = 50;
    
            Hero teemo = new Hero();
            teemo.name = "提莫";
            teemo.hp = 300;
            teemo.damage = 30;
    
            Hero bh = new Hero();
            bh.name = "赏金猎人";
            bh.hp = 500;
            bh.damage = 65;
    
            Hero leesin = new Hero();
            leesin.name = "盲僧";
            leesin.hp = 455;
            leesin.damage = 80;
    
            //创建一个实现线程类的类的对象  但是这个对象没有start方法
            Battle battle1 = new Battle(gareen, teemo);
    
            new Thread(battle1).start();   //我们就将这个对象 传到Thread中 调用其中的start方法
    
            Battle battle2 = new Battle(bh, leesin);
            new Thread(battle2).start();
    
            //两种创建线程的方法
            //1、继承Thread方法   直接声明run方法  然后调用父类Thread的start启动线程
            //2、实现Runnable接口   重写run方法  实例化该类,得到对象传入Thread构造方法中  调用其中的start方法 启动线程
        }
    }

      3、编写内部类,类中创建线程,调用该线程对象的start方法。补充:内部类可以调用外部类的变量

    package com.thread.thread3;
    
    import com.thread.Hero;
    
    public class TestT {
        public static void main(String[] args) {
            Hero gareen = new Hero();
            gareen.name = "盖伦";
            gareen.hp = 616;
            gareen.damage = 50;
    
            Hero teemo = new Hero();
            teemo.name = "提莫";
            teemo.hp = 300;
            teemo.damage = 30;
    
            Hero bh = new Hero();
            bh.name = "赏金猎人";
            bh.hp = 500;
            bh.damage = 65;
    
            Hero leesin = new Hero();
            leesin.name = "盲僧";
            leesin.hp = 455;
            leesin.damage = 80;
    
            //匿名类
            Thread t1 = new Thread() {   //匿名类  创建一个匿名对象
                public void run() {   //重新实现它的run方法
    
                    //匿名类中用到的外部的局部变量teemo 必须把teemo声明成final
                    //但是jdk7后  就不用加上final了
                    while(!teemo.isDead()) {
                        gareen.attackHero(teemo);
                    }
                }
            };
            t1.start();  //调用该内部类的方法  启动线程对象
    
            Thread t2 = new Thread() {
                public void run() {
                    while(!leesin.isDead()) {
                        bh.attackHero(leesin);
                    }
                }
            };
            t2.start();  //启动第二个线程
        }
    }

    总结


       线程的创建要么是创建本质都是实例Thread类,重写run方法(这个run方法是runnable接口中的),执行Thread类中的start方法启动线程。Thread类是实现Runnable接口的。

  • 相关阅读:
    ES 2016+
    git-svn for mac
    Linux系统下安装rz/sz命令及使用说明
    Nginx location指令匹配顺序规则
    nginx修改配置后不生效的问题
    ssh and scp从远程服务器下载文件
    安装yii2 框架遇到的问题
    php添加openssl扩展
    GitHub Token for composer
    centos7+nginx+php+mysql环境搭建
  • 原文地址:https://www.cnblogs.com/HelloM/p/14403290.html
Copyright © 2020-2023  润新知