线程类以及创建多线程的第一种方式---继承Thread类

先来看一个例子理解主线程和单线程:

/*
主线程:执行主(main)方法的线程
单线程程序:Java程序中只有一个线程
程序从main方法开始,从上到下依次执行
 */
public class Demo11MainThread {
    public static void main(String[] args) {
        Person p1 = new Person("易烊千玺",18);
        Person p2 = new Person("王俊凯",19);
        p1.run();
        p2.run();
    }
}

过程:

首先JVM执行应用程序,main方法,从方法区进入到栈中,JVM会找操作系统开辟一条main方法通向cpu的执行路径(线程),然后cpu就可以通过这个路径来执行main方法,这个路径名字就是主线程。

单线程弊端:由于是从上到下依次执行,中间有环节出现异常的时候,后面的任务也会终止,因此引入多线程的使用。

创建线程类

Java使用java.lang.Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例,每个线程的作用是完成一定的任务,实际上就是执行一段程序即一段顺利执行的代码。Java使用线程执行体来代表这段程序流。

Java创建多线程有两种方式:

第一种:Java中通过继承Thread类来创建并启动多线程的步骤如下:

1.定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把run()方法称为线程执行体。

2.创建Thread子类的实例,即创建了线程对象

3.调用线程对象的start()方法来启动该线程

 void

start()
          使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

结果是两个线程并发地运行;当前线程(main线程)和另一个线程(创建的新线程,执行其 run 方法):

多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

Java程序属于抢占式调度,哪个线程的优先级高,就先执行,优先级相同,就随机选择一个执行。

/*
线程类的子类,重写run()方法
 */
public class MyThread extends Thread{
    // 1.定义Thread类的子类,并重写该类的run()方法
    @Override
    public void run() {
        // super.run();
        for (int i = 0; i < 20; i++) {
            System.out.println("run" + i);
        }
    }
}
public class Demo11Thread {
    public static void main(String[] args) { // 并发运行的第一个线程
        // 2.创建Thread类的子类对象
        MyThread mt = new MyThread();
        // 调用Thread类中的方法start方法,开启新的线程,执行run()方法
        mt.start(); // 开启新的(第二个线程)

        for (int i = 0; i < 20; i++) { // 主线程的代码块
            System.out.println("main" + i);
        }
    }
}

执行结果:

从结果可以看出来,Java采用抢占式调度,优先级相同,随机选择执行。

多线程运行原理

以上述代码举例,解释多线程程序的执行流程:

多线程内存图解

main方法压栈执行,new的对象在堆内存中分配一块空间,并将内存地址值赋值给相应变量mt,执行mt.run(),方法压栈运行(此时为单线程,是对象调用方法,而不是创建新的线程),运行到mt.start()时,并不是方法压栈执行,而是开辟一个新的栈空间。

猜你喜欢

转载自blog.csdn.net/wardo_l/article/details/114220235