多线程
进程:进程指正在运行的程序
线程:是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个线程中是可以有多个线程的,这个应用程序也可以被称为多线程程序。
一个程序运行后至少有一个进程,一个进程中可以包含多个线程
举例:
单线程程序:即,若有多个任务只能依次执行。当上一个任务执行结束后,下一个任务开始执行。
如,去网吧上网,网吧只能让一个人上网,当这个人下机后,下一个人才能上网。
多线程程序:即,若有多个任务可以同时执行。如,去网吧上网,网吧能够让多个人同时上网。
程序运行原理
分时调度
所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。
抢占式调度
优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。
主线程
代码演示:
1 class Demo{
2 String name;
3 Demo(String name){
4 this.name = name;
5 }
6 void show() {
7 for (int i=1;i<=10000 ;i++ ) {
8 System.out.println("name="+name+",i="+i);
9 }
10 }
11 }
12
13 class ThreadDemo {
14 public static void main(String[] args) {
15 Demo d = new Demo("小强");
16 Demo d2 = new Demo("旺财");
17 d.show();
18 d2.show();
19 System.out.println("Hello World!");
20 }
21 }
jvm启动后,必然有一个执行路径(线程)从main方法开始的,一直执行到main方法结束,这个线程在java中称之为主线程。
Thread类
构造方法:
常用方法:
创建线程方式一继承Thread类
代码演示:
1 public class MyThread extends Thread{
2 MyThread(){
3
4 }
5 public MyThread(String name){
6 super(name);
7 }
8 public void run() {
9 System.out.println(super.getName());
10 /*for(int j=0;j<10;j++){
11 System.out.println("run....."+j);
12 }*/
13 }
14
15 }
16
17 测试类:
18 public class Demo01 {
19 // "main"主线程
20 public static void main(String[] args) {
21 //获取当前执行该方法的线程对象
22 Thread m=Thread.currentThread();
23 //获取线程对象的名称
24 System.out.println(m.getName());
25 //System.out.println(0/0);
26 //新建一个线程
27 MyThread th=new MyThread("蔡文奶");
28 //th.setName("蔡文奶");
29 //开启线程
30 th.start();
31 /*for(int i=0;i<10;i++){
32 System.out.println("main..."+i);
33 }*/
34 }
35
36 }
线程对象调用 run方法和调用start方法区别?
线程对象调用run方法不开启线程。仅是对象调用方法。线程对象调用start开启线程,并让jvm调用run方法在开启的线程中执行。
多线程图解:
获取线程名称
代码演示:
1 class MyThread extends Thread { //继承Thread
2 MyThread(String name){
3 super(name);
4 }
5 //复写其中的run方法
6 public void run(){
7 for (int i=1;i<=20 ;i++ ){
8 System.out.println(Thread.currentThread().getName()+",i="+i);
9 }
10 }
11 }
12 class ThreadDemo {
13 public static void main(String[] args) {
14 //创建两个线程任务
15 MyThread d = new MyThread();
16 MyThread d2 = new MyThread();
17 d.run();//没有开启新线程, 在主线程调用run方法
18 d2.start();//开启一个新线程,新线程调用run方法
19 }
20 }
创建线程方式—实现Runnable接口
接口中的方法:
Thread类构造方法
代码演示:
1 public class Demo02 {
2 public static void main(String[] args) {
3 //创建线程执行目标类对象
4 Runnable runn = new MyRunnable();
5 //将Runnable接口的子类对象作为参数传递给Thread类的构造函数
6 Thread thread = new Thread(runn);
7 Thread thread2 = new Thread(runn);
8 //开启线程
9 thread.start();
10 thread2.start();
11 for (int i = 0; i < 10; i++) {
12 System.out.println("main线程:正在执行!"+i);
13 }
14 }
15 }
16 自定义线程执行任务类
17 public class MyRunnable implements Runnable{
18
19 //定义线程要执行的run方法逻辑
20 @Override
21 public void run() {
22
23 for (int i = 0; i < 10; i++) {
24 System.out.println("我的线程:正在执行!"+i);
25 }
26 }
27 }
线程的匿名内部类使用
方法一:
1 public class Demo01 {
2 public static void main(String[] args) {
3 //匿名内部类
4 new Thread(){
5 public void run() {
6 for(int i=0;i<50;i++){
7 System.out.println("run..."+i);
8 }
9 }
10 }.start();
11 }
12
13 }
方式2:使用匿名内部类的方式实现Runnable接口,重新Runnable接口中的run方法
1 public class Demo02 {
2 public static void main(String[] args) {
3 Runnable run=new Runnable(){
4 public void run() {
5 for(int i=0;i<50;i++){
6 System.out.println("run..."+i);
7 }
8 }
9 };
10 Thread th=new Thread(run);
11 th.start();
12 //简化
13 new Thread(new Runnable(){
14 public void run() {
15 for(int i=0;i<50;i++){
16 System.out.println("run..."+i);
17 }
18 }
19 }).start();
20 }
21
22 }