hello 大家好,相信有很多学习java的小伙伴和以及工作的朋友们,本文呢主要讲多线程的概念和创建与启动,剩余的部分内容回尽快更新哈
前言
虽然说在实际工作当中,我们可能编写关于多线程的代码比较少,但是我们一定会是在一个多线程的环境下去研发,所以也就体现出了多线程的重要性,而且像大厂的面试也会经常问到,所以多线程一定是一门必修课:
以下是本篇文章正文内容,下面案例可供参考,建议先写代码再看运行原理!
一、多线程的运行原理
首先启动Java程序会开启java虚拟机,JVM,这样也就等于打开一个应用程序也就是进程,进程会生成主线程,主线程会找某个类的main方法,也就是说main方法是运行在主线程中,当程序执行到创建线程对象的时候,我们的t变量会指向堆内存的Thread线程对象,程序执行到t.start方法时会向JVM申请开辟一块新的栈,这个时候就有了两个线程,一个主线程和一个t线程,t.start()并不会在main的栈内存进行压栈,如果main线程的栈弹空了也不会跟t线程有关系,两个栈之间是独立关系,t线程对象的方法执行会压在t栈中。
二、JAVA创建线程的两种方式(推荐Runnable)
这是我常用的两种,并不止两种!
1.继承Thread
使用这种方式需要去继承Thread并且重写run方法
public class ThreadTest extends Thread{
@Override
public void run() {
for(int i = 0;i<100;i++){
System.out.println("run-->"+i);
}
}
}
public class Thread01{
public static void main(String[]args){
//多态
Thread t = new ThreadTest();
//t.start();代表启动线程,start方法会向JVM申请开辟一块新的栈内存空间,并且不需要我们手动去调用run方法,如果我们调用
//t.run方法是不会开启线程的,当主线程结束程序也就结束了
t.start();
//t.run();这只是普通的方法调用,这样做并不会开启线程,也不会开辟新的栈内存
for (int a = 0;a<10;a++){
System.out.println("MAIM-->"+a);
}
}
}
使用Thread去创建线程需要用到多态,并且调用Thread的start方法去启动线程,start方法会向JVM申请开辟一块新的栈内存空间,并且不需要我们手动去调用run方法,如果我们调用t.run方法是不会开启线程的,当主线程结束程序也就结束了。
这里涉及到一个问题是调用重写的run方法和调用start方法有什么区别,答案是调用run方法只会是一个普通的方法调用,不会开启线程也不会像JVM去开辟新的栈内存空间。
2.实现Runnable接口
这种创建方式和继承Thread不太一样,首先需要实现Runnable接口,实现Runnable接口的run方法,不需要多态去引向子类,但是需要将实现Runnable接口的类作为参数传递给new Thread()中然后调用start方法则创建线程。
public class ThreadTest2 {
public static void main(String[]args){
Thread t = new Thread(new RunnableTest());
t.start();
for (int i = 0 ; i < 10; i++){
System.out.println("main->"+i);
}
}
}
实现Runnable接口
public class RunnableTest implements Runnable{
@Override
public void run() {
for (int i = 0 ; i <10; i++){
System.out.println("run-->"+i);
}
}
}
运行结果:
main->0
main->1
run–>0
run–>1
run–>2
main->2
main->3
main->4
main->5
main->6
run–>3
run–>4
run–>5
run–>6
run–>7
run–>8
run–>9
main->7
main->8
main->9
运行结果之所以会是交替执行,后面在多线程的生命周期中讲到。