一、基本概念:程序-进程-线程
1.程序(program)是为完成特定任务、用某种语言编写的一组指定的结合。即指一段静态的代码,静态对象。
2.进程(process)是程序的一次执行过程,或是正在进行的一个程序。
动态过程:由它自身的产生、存在和消亡的过程。
①如:运行中的qq,运行中的播放器
②程序是静态的,进程是动态的。
3.线程(thread),进程可进一步细化为线程,是一个程序内部的执行路径。
①若一个程序可同一时间执行多个线程,就是支持多线程的。
二、何时需要多线程
1.程序需要同时执行两个或多个任务。
2.程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
3.需要一些后台运行的程序时。
三、多线程的创建和启动
1.Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread类来实现。
2.Thread类的特性
①每个线程都是通过某个特定的Thread对象的run()方法来完成操作的,经常把run()方法的主体称为线程体。
②通过该Thread对象的start()方法来调用这个线程。
3.Thread类的构造方法
①Thread():创建新的Thread对象
②Thread(String threadname):创建线程并指定线程实例名
③Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接口中的run方法
④Thread(Runnable target,String name):创建新的Thread对象
四、创建线程的两种方式
1.继承Thread类
①定义子类继承Thread类。
②子类中重写Thread类中的run方法。
③创建Thread子类对象,即创建了线程对象。
④调用线程对象start方法:启动线程,调用run方法。
package day20; /* *继承Thread的方式实现多线程 */ public class TestThread extends Thread{ @Override public void run() { // TODO Auto-generated method stub System.out.println("多线程运行的代码"); for(int i = 0; i < 5; i++){ System.out.println("这是多线程的逻辑代码:" + i); } } }
package day20; public class Test { public static void main(String[] args){ Thread t0 = new TestThread(); t0.start();//启动线程,开始运行run方法中的代码 System.out.println("-------------------1"); System.out.println("-------------------2"); System.out.println("-------------------3"); /** * 开启了线程之后的run方法中运行的代码与主程序中t0.start()之后的程序是并行执行的,没有先后关系,这个叫异步 * */ } }
打印结果:
2.实现Runnable接口
①定义子类,实现Runnable接口。
②子类中重写Runnable接口中的run方法。
③通过Thread类含参构造器创建线程对象。
④将Runnable接口的子类对象作为实际参数传递给Thread类的构造方法中。
⑤调用Thread类的strat方法:开启线程,调用Runnable子类接口的run方法。
package day20; /** * 通过实现Runnable接口方式实现多线程 * */ public class TestRunnable implements Runnable{ public void run() { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName() + ":Runnable多线程运行的代码"); for(int i = 0; i < 5; i++){ System.out.println(Thread.currentThread().getName() + ":这是Runnable多线程的逻辑代码:" + i); } } }
package day20; public class Test { public static void main(String[] args){ // Thread t3 = new Thread(new TestRunnable()); // t3.start(); Thread t4 = new Thread(new TestRunnable(),"t-1"); t4.start(); System.out.println("-------------------1"); System.out.println("-------------------2"); System.out.println("-------------------3"); /** * 开启了线程之后的run方法中运行的代码与主程序中t0.start()之后的程序是并行执行的,没有先后关系,这个叫异步 * */ } }
打印结果:
五、继承方式和实现方式的联系与区别
1.联系:public class Thread extends Object implements Runnable//都需要Thread类
2.区别:
①继承Thread:线程代码存放Thread子类run方法中。(重写run方法)
②实现Runnable:线程代码存在接口的子类的run方法。(实现run方法)
3.实现接口方式的好处:
一般使用实现接口方式来实现多线程。
①避免了单继承的局限性。
②多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。
package day20; /** * 通过实现Runnable接口方式实现多线程 * */ public class TestRunnable implements Runnable{ int count = 0;//通过count测试共享 public void run() { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName() + ":Runnable多线程运行的代码"); for(int i = 0; i < 5; i++){ count ++; System.out.println(Thread.currentThread().getName() + ":这是Runnable多线程的逻辑代码:" + count); } } }
package day20; public class Test { public static void main(String[] args){ Runnable run = new TestRunnable(); Thread t5 = new Thread(run,"t-1"); t5.start(); Thread t6 = new Thread(run,"t-2"); t6.start(); System.out.println("-------------------1"); System.out.println("-------------------2"); System.out.println("-------------------3"); } }
打印结果://开启两个线程,countd叠加到了10
六、使用多线程的优点
1.提高程序的响应。对图形化界面更有意义,可增强用户体验。
2.提高计算机系统CPU的利用率。
3.改善程序结构,将既长又复杂的进程分为多个线程,彼此独立运行,利于理解和修改。