1.进程、线程、并发、并行是什么?
1)进程:操作系统中可以运行多个任务(程序),这些运行的任务(程序)被称为进程。程序的运行产生进程(内存空间、程序执行的堆栈),可以这样说,进程是作为操作系统分配资源的基本单位。
2)线程:程序里同时可能运行多个任务(在一个CPU时间片内,顺序执行流),那么每个任务(顺序执行流)就叫做一个线程,即在线程内部。
3)并发:线程是并发运行的。操作系统将时间化分为若干个片段(时间片),尽可能的均匀分配给每一个任务,被分配时间片后,任务就有机会被cpu所执行。微观上看,每个任务都是走走停停的。但随着cpu高效的运行,宏观上看所有任务都在运行。这种都运行的现象称之为并发,但不是绝对意义上的“同时发生”。
4)并行:一个时间段,多个任务同时进行,而且多个CPU运行各自的进程。
2.多线程的实现
1)继承Thread
通过查阅JDK API文档,Thread 类位于java.lang中,表示进程中的执行线程。实现多线程有两种方式。第一是继承Thread:
1 package cn.a1.a; 2 3 public class MyThread extends Thread { 4 5 @Override 6 public void run() { 7 System.out.println("这是多线程MyThread"); 8 for (int i = 0; i < 5; i++) { 9 System.out.println("MyThread:" + i);10 }11 12 }13 }
1 package cn.a1.a; 2 3 public class Test1 { 4 public static void main(String[] args) { 5 // 创建一个多线程,此时已有两个线程 主线程(main) 和 创建的线程 mThread1; 6 MyThread mThread1 = new MyThread(); 7 mThread1.start(); 8 9 // 查看主线程main是否运行10 for (int i = 0; i < 5; i++) {11 System.out.println("main Thread:" + i);12 }13 14 }15 16 }
main线程和t1线程抢占CPU 执行,输出也是main线程和t1线程根据内部抢占CPU 执行输出,不规则,多线程在提高CPU利用率的同时,增加程序的复杂度。
main Thread:0这是多线程MyThreadmain Thread:1MyThread:0main Thread:2MyThread:1main Thread:3MyThread:2MyThread:3main Thread:4MyThread:4
2)实现Runnable接口
用于定义线程要执行的任务逻辑。我们定一个类实现Runnable接口,这时我们必须重写run方法,在其中定义我们要执行的逻辑。之后将Runnable交给线程去执行。从而实现了线程与其执行的任务分离开。将任务分别交给不同的线程并发处理,可以使用线程的重载构造方法:Thread(Runnable runnable)。解藕:线程与线程体解藕,即打断依赖关系。 如果你学到Spring了就知道,Spring的ioc就是干这个的。
演示:
1 package cn.a1.a1; 2 3 public class MyRun implements Runnable { 4 5 @Override 6 public void run() { 7 System.out.println("这是MyRun"); 8 9 for (int i = 0; i < 3; i++) {10 System.out.println("MyRun:" + i);11 }12 }13 }
1 public class Test1 { 2 public static void main(String[] args) { 3 MyRun tRun1 = new MyRun(); 4 Thread t1 = new Thread(tRun1); 5 t1.start(); 6 //这里main开始运行也有产生一个进程,该进程有个主(main)线程 7 for (int i = 0; i < 3; i++) { 8 System.out.println("main"+i); 9 }10 11 }12 13 }
输出不规则的
main0这是MyRunMyRun:0main1main2MyRun:1MyRun:2
继承Thread和实现Runnable接口实现多线程的优缺点
[1] 继承Thread的线程类不能再继承其他类,实现Runnable接口的类还可以继承其他类。
[2] 实现Runnable接口的线程类,可以让多个线程共享线程实现类的资源。
总结:
多线程提高了cpu利用率,但程序的复杂度也随之增加。一旦线程开始执行,很难通过其他方式控制线程的轨迹。
多个线程抢占CPU导致线程的运行轨迹不确定。