网站建设时间及简介,seo线上培训多少钱,软件界面设计与色彩搭配,uniform wordpress目录
多线程
1.1 并发和并行
1.2 线程和进程
1.2.1 进程
1.2.2 线程
1.3 单线程
1.3.1 单线程案例
1.4 创建多线程的方式
1.4.1 继承Thread类
1.4.2 实现Runnable接口
1.4.3 使用匿名内部类
1.5 Thread类
1.5.1 构造方法
1.5.2 常用方法
1.5.3 Thread类中…目录
多线程
1.1 并发和并行
1.2 线程和进程
1.2.1 进程
1.2.2 线程
1.3 单线程
1.3.1 单线程案例
1.4 创建多线程的方式
1.4.1 继承Thread类
1.4.2 实现Runnable接口
1.4.3 使用匿名内部类
1.5 Thread类
1.5.1 构造方法
1.5.2 常用方法
1.5.3 Thread类中的常用方法练习 多线程 指在一个程序中同时运行多个线程每个线程可以执行不同的任务。多线程可以提高程序的性能和响应速度充分利用计算机的多核处理能力。同时多线程也可以实现任务的并发执行提升程序的效率。多线程之间可以共享数据但也需要注意线程安全的问题。
1.1 并发和并行
并发指两个或多个事件在同一个时间段内发生交替执行。并行指两个或多个事件在同一时刻发生同时执行。 1.2 进程和线程
1.2.1 进程 指一个内存中运行的应用程序每一个进程都有一个独立的内存空间一个应用程序可以同时运行多个进程进程也是程序的一次执行过程是系统运行程序的基本单位系统运行一个程序即是一个进程从创建、运行到消亡的过程。
1.2.2 线程 线程是进程中的一个执行单元负责当前进程中程序的执行一个进程中至少有一个线程一个进程中是可以有多个线程的这个应用程序也可以称之为多线程程序。
注一个程序运行后至少有一个进程一个进程中可以包含多个线程。 1.3 单线程 指java程序只有一个线程main方法的线程执行从main方法开始从上到下依次执行执行过程如下
JVM执行main方法main方法会进入到栈内存。JVM会找操作系统开辟一条main方法通向CPU的执行路径。CPU就可以通过这个路径来执行main方法。而这个路径有一个名字叫main主线程。
1.3.1 单线程案例 场景 模拟王者游戏中两组英雄进行攻击米莱迪 攻击 诸葛亮 and 亚瑟 攻击 猪八戒下面是采用单线程的方式实现。 Hero.java角色类
package com.zhy.multiplethread;public class Hero{/*** 角色名称*/public String name;/*** 角色血量*/public float hp;/*** 攻击伤害*/public int damage;public Hero(){ }public Hero(String name,float hp,int damage){this.name name;this.hp hp;this.damage damage;}/*** 角色攻击方法* param h*/public void attackHero(Hero h) {try {//攻击需要时间每次攻击暂停1000毫秒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 已被击杀);}}/*** 判断角色是否已被击杀根据血量判断血量0返回true否则返回false* return*/public boolean isDead() {return 0 hp ? true : false;}
}
TestThread.java测试类
package com.zhy.multiplethread;public class TestThread {public static void main(String[] args) {Hero hero1 new Hero(米莱迪,350,60);Hero hero2 new Hero(诸葛亮,300,50);Hero hero3 new Hero(亚瑟,450,70);Hero hero4 new Hero(猪八戒,400,60);//米莱迪 攻击 诸葛亮while(!hero2.isDead()){hero1.attackHero(hero2);}//亚瑟 攻击 猪八戒while(!hero4.isDead()){hero3.attackHero(hero4);}}
}输出结果 使用单线程实现可以看出第二组英雄 是在 第一组英雄攻击完毕后 才开始攻击的。 1.4 创建多线程的方式 创建多线程的常用方式有三种第一种是继承Thread类第二种是实现Runnable接口第三种是直接使用匿名内部类进行具体实现。下面我们依次进行详细解析。
1.4.1 继承Thread类 java.lang.Thread类Java线程模型的基础只需要继承Thread类并重写run()方法来定义线程的执行逻辑。然后可以通过创建Thread的实例来启动线程。 实现步骤 创建一个Thread类的子类。在Thread类的子类中重写Thread类中的run()方法设置线程任务具体业务场景。创建Thread类的子类对象为实例。调用Thread类中的start方法开启新的线程实际是执行的run()方法。 注意事项 void start()使该线程开始执行java虚拟机调用该线程的run()方法。启动线程后实际是两个线程并发的运行当前线程main线程和另一个线程创建的新线程执行其run()方法。多次启动一个线程是非法的特别是当线程已经结束执行后不能在重新启动。 代码示例 场景 模拟王者游戏中两组英雄进行攻击米莱迪 攻击 诸葛亮 and 亚瑟 攻击 猪八戒下面是采用多线程的方式实现。 KillThread.javaThread的子类
package com.zhy.multiplethread;/*** 1.创建一个Thread类的子类。*/
public class KillThread extends Thread{private Hero h1;private Hero h2;public KillThread(Hero h1, Hero h2){this.h1 h1;this.h2 h2;}/*** 2.在子类中重写Thread类中的run()方法设置线程任务。* 当角色h2没有被击杀时角色h1持续进行攻击*/public void run(){while(!h2.isDead()){h1.attackHero(h2);}}
} TestThread.java测试类
package com.zhy.multiplethread;public class TestThread {public static void main(String[] args) {Hero hero1 new Hero(米莱迪,350,60);Hero hero2 new Hero(诸葛亮,300,50);Hero hero3 new Hero(亚瑟,450,70);Hero hero4 new Hero(猪八戒,400,60);//3.创建Thread类的子类对象KillThread killThread1 new KillThread(hero1,hero2);KillThread killThread2 new KillThread(hero3,hero4);//4.调用Thread类中的start方法开启新的线程实际是执行的run()方法。killThread1.start();killThread2.start();}
}输出结果 java程序属于抢占式调度哪个线程的优先级高哪个线程就先执行同一个优先级随机选择一个执行。从输出中可以看到第一组英雄 还没攻击完毕 第二组英雄就开始攻击了可以很大程度的提高程序的性能和速度。 1.4.2 实现Runnable接口 java.lang.Runnable接口实现Runnable接口的类可以作为Thread类的构造函数参数来创建线程。这种方式更加灵活因为Java不支持多继承所以实现Runnable接口可以使类在同时继承其他类的情况下创建线程。 构造方法 Thread(Runnable target)分配新的Thread对象。 Thread(Runnable target,String name)分配新的Thread对象。 实现步骤 创建一个Runnable接口的实现类。在实现类中重写Runnable接口的run方法设置线程任务。创建一个Runnable接口的实现类对象。创建Thread类对象构造方法中传递Runnable接口的实现类对象。调用Thread类中的start方法开启新的线程执行run方法。 代码示例 场景同上 Battle.javaRunnable的实现类
package com.zhy.multiplethread;/*** 1.创建一个Runnable接口的实现类*/
public class Battle implements Runnable{private Hero h1;private Hero h2;public Battle(Hero h1, Hero h2){this.h1 h1;this.h2 h2;}/*** 2.在实现类中重写Runnable接口的run方法设置线程任务*/public void run(){while(!h2.isDead()){h1.attackHero(h2);}}
} TestThread.java测试类
package com.zhy.multiplethread;public class TestThread {public static void main(String[] args) {Hero hero1 new Hero(米莱迪,350,60);Hero hero2 new Hero(诸葛亮,300,50);Hero hero3 new Hero(亚瑟,450,70);Hero hero4 new Hero(猪八戒,400,60);//3.创建一个Runnable接口的实现类对象Battle battle1 new Battle(hero1,hero2);Battle battle2 new Battle(hero3,hero4);//4.创建Thread类对象构造方法中传递Runnable接口的实现类对象;调用Thread类中的start方法开启新的线程执行run方法new Thread(battle1).start();new Thread(battle2).start();}
}实现Runnable接口创建多线程程序的好处
实现了Runnable接口还可以继承其他的类实现其他的接口避免了单继承的局限性。把设置线程任务和开启新线程进行了分离增强了程序的扩展性降低了程序的耦合性解耦。
1.4.3 使用匿名内部类
匿名没有名字。内部类存在其他类内部的类。 格式 new 父类/接口(){ 重写父类/接口中的方法 }; 作用简化代码 实现方式 把子类继承父类重写父类的方法创建子类对象合一步完成。把实现类实现接口重写接口中的方法创建实现类对象合成一步完成。匿名内部类的最终产物子类/实现类对象而这个类没有名字。 代码示例 场景同上 TestThread.java测试类
package com.zhy.multiplethread;public class TestThread {public static void main(String[] args) {Hero hero1 new Hero(米莱迪,350,60);Hero hero2 new Hero(诸葛亮,300,50);Hero hero3 new Hero(亚瑟,450,70);Hero hero4 new Hero(猪八戒,400,60);//匿名类线程的父类是Threadnew Thread(){public void run(){while(!hero2.isDead()){hero1.attackHero(hero2);}}}.start();//匿名类线程的接口是Runnablenew Thread(new Runnable() {Overridepublic void run() {while(!hero4.isDead()){hero3.attackHero(hero4);}}}).start();}
}1.5 Thread类
1.5.1 构造方法
Thread()分配一个新线程对象。Thread(String name)分配一个指定名字的新线程对象。Thread(Runnable target)分配一个带有指定目标的新线程对象。Thread(Runnable target,String name)分配一个带有指定目标的新线程对象并指定名字。
1.5.2 常用方法
String getName()获取当前线程的名称。void start()启动当前线程java虚拟机调用当前线程的run方法。void run()当前线程要执行的任务在此处定义代码。static void sleep(long millis)使当前正在执行的线程以指定的毫秒数暂停。static Thread currentThread()返回对当前正在执行的线程对象的引用。
1.5.3 Thread类中的常用方法练习 场景模拟 秒针 的转动每隔一秒执行依次。 package com.zhy.thread;//继承自Thread类
public class ThreadTest extends Thread{//定义一个无参构造方法public ThreadTest(){}//定义一个有参构造方法public ThreadTest(String name){super(name);}//重写父类中的run方法Overridepublic void run() {//获取当前正在执行的线程对象Thread thread Thread.currentThread();//获取当前线程的名称String threadName thread.getName();System.out.println(threadName);//也可以直接分成一步实现采用链式编程System.out.println(Thread.currentThread().getName());}public static void main(String[] args) {//启动多线程1ThreadTest threadTest new ThreadTest();threadTest.setName(xiaoQiang);threadTest.start();//启动多线程2new ThreadTest(wancai).start();//模拟秒针每隔一秒执行一次for (int i 1; i 60; i){System.out.println(i);try {//该方法是一个编译时异常必须处理Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}}}
}