-
基本概念
- 程序 (program) 是为完成特定任务、用某种语言编写的一组指令的集合,即指一段静态的代码,静态对象。
- 进程 (process) 是程序的一次执行过程,或正在运行的一个程序。是一个 动态的过程:有它自身的产生、存在和消亡过程。——生命周期
- 线程 (thread) 进程可一步细化为线程,是一个程序内部的一条执行路径。
- 若一个进程同时间并行执行多个线程,就是支持多线程的
- 线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc),线程切换的开 销小
- 一个进程中的多线程共享相同的内存单元/内存地址空间(它们从同一堆中分配对象,可以 访问相同的变量和对象)。这就使得线程间通信更简便、高效,但多个线程操作共享系统资源可能就会带来安全的隐患 。
- 单核CPU 其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程的任务。(eg:一个厨师炒几桌菜)
- 多核CPU 如果是多核CPU,才能更好的发挥多线程的效率。(现在的服务器都是多核的)
- 并行: 多个CPU同时执行多个任务。(eg:多个人做不的事,同时执行多个任务。)
- 并发:一个CPU(采用时间片)同时执行多个任务。(eg:秒杀、多个人做同一件事。)
-
多线程的优点
背景:以单核CPU为例,只使用单个线程先后完成多个任务(调用多个方法),肯定比用多个线程来完成用的时间更短(因为需要高速切换线程)
多线程程序优点?
提高应用程序的响应,对图形化界面更有意义,可增强用户的体验
提高计算机系统CPU的利用率
改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改
何时需要多线程?
程序需要同时执行两个或多个任务。
程序需要实现一些需要等待的任务时,如用户输入、文件读写
操作、网络操作、搜索等。
需要一些后台运行的程序时。
-
多线程的创建
-
1.继承Thread类
步骤:
- 创建一个继承于Thread类的子类
- 重写Thread类的run(),将此线程执行的操作声明在run()中
- 创建Thread类的子类对象
- 通过对象调用Thread类中start():①启动当前线程 ②调用当前线程的run方法
-
package com.atiguigu.java;
/**
* 多线程的创建:
*①.继承Thread类
* 步骤:
*
* 创建一个继承于Thread类的子类
* 重写Thread类的run(),将此线程执行的操作声明在run()中
* 创建Thread类的子类对象
* 通过对象调用Thread类中start():
* start()方法的两个作用: ①启动当前线程 ②调用当前线程的run方法
*
* 例子:遍历100以内的所有偶数
* * @author
* @create 2021-02-23 9:54
*/
class MyThread extends Thread {
//重写Thread类的run(),将此线程执行的操作声明在run()中
@Override
public void run() {
//遍历100以内的所有偶数
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println(i);
}
}
}
public static class ThreadTest {
public static void main(String[] args) {
// 创建Thread类的子类对象
MyThread t1 = new MyThread();
// 过对象调用Thread类中start():
t1.start();
System.out.println("hello");
//①启动当前线程 ②调用当前线程的run方法
}
}
}
package com.atiguigu.java; /** * 练习:创建2个多线程,其中一个便利100以内的偶数,一个便利100以内的奇数 * @author * @create 2021-02-23 10:17 */ //public class ThreadDemo { // public static void main(String[] args) { // MyThread1 m1 = new MyThread1(); // MyThread2 m2 = new MyThread2(); // // m1.start(); // m2.start(); // } //} // 遍历偶数 //class MyThread1 extends Thread{ // @Override // public void run() { // for (int i =0;i<100;i++){ // if(i%2==0){ // System.out.println(Thread.currentThread().getName()+":"+i); // } // } // } //} // 遍历奇数 //class MyThread2 extends Thread{ // @Override // public void run() { // for (int i =0;i<100;i++){ // if(i%2!=0){ // System.out.println(Thread.currentThread().getName()+":"+i); // } // } // } //} //方法二 //创建Thread匿名子类 public class ThreadDemo { public static void main(String[] args) { new Thread() { @Override public void run() { for (int i = 0; i < 100; i++) { if (i % 2 == 0) { System.out.println(Thread.currentThread().getName() + ":" + i); } } } }.start(); new Thread(){ @Override public void run() { for (int i = 0; i < 100; i++) { if (i % 2 != 0) { System.out.println(Thread.currentThread().getName() + ":" + i); } } } }.start(); } }
start()方法来启动线程,真正实现了多线程运行。
start方法的作用就是将线程由创建状态,变为就绪状态。当线程创建成功时,线程处于创建状态,如果你不调用start( )方法,那么线程永远处于创建状态。调用start( )后,才会变为就绪状态,线程才可以被CPU运行。
<