现实生活中的很多事情是同时进行的,Java中为了模拟这种状态,引入了线程机制。先来看线程的基本概念。
线程是指进程中的一个执行场景,也就是执行流程,进程和线程的区别:
1.每个进程是一个应用程序,都有独立的内存空间。
2.同一个进程中的线程共享其进程中的内存和资源。
(共享的内存是堆内存和方法区内存,栈内存不共享,每个线程有自己的栈内存)
我们还需要了解以下基本内容:
1.什么是进程?
一个进程对应一个应用程序。例如:在Windows操作系统启动word就表示启动了一个进程。在Java开发环境下启动JVM,就表示启动了一个进程。现在的计算机都是支持多进程的,在同一个操作系统中,可以同时启动多个进程。
2.多进程有什么作用?
单进程计算机只能做一件事情。
玩电脑,一边打游戏(游戏进程)一边听音乐(音乐进程)。
对于单核计算机来讲,在同一个时间点上,游戏进程和音乐进程是在同时运行吗? 不是。
因为计算机的CPU只能在某个时间点上做一件事情。由于计算机将在“游戏进程”和“音乐进程”之间频繁地切换执行,切换速度极高,人类感觉游戏和音乐同时在进行。
多进程的作用不是提高执行速度,而是提高CPU的使用率。
进程和进程之间的内存是独立的。
3.什么是线程?
线程是一个进程中的执行场景。一个进程可以启动多个线程。
4.多线程有什么作用?
多线程不是为了提高执行速度,而是提高应用程序的使用率。
线程和线程共享“堆内存和方法区内存”,栈内存是独立的,一个线程一个栈。
5.Java程序的运行原理?
Java命令会启动Java虚拟机,启动JVM,等于启动了一个进程,该进程会自动启动一个“主线程”,然后主线程去调用某个类的main方法,所以main方法运行在主线程中。在此之前的所有程序都是单线程的。
理论知识有了,接下来试着分析以下程序有几个线程?
public class ThreadTest01{ public static void main(String[] args){ m1(); } public static void m1(){ m2(); } public static void m2(){ m3(); } public static void m3(){ System.out.println("asfs"); }}
上面程序只有一个线程,就是主线程。main()方法调m1();m1()调m2();m2()调m3(),所以main()方法以及m1();m2();m3();方法在同一个栈中。由于进程与进程的栈是独立的,所以只有一个进程。
在Java中实现线程的两种方式,分别为继承java.lang.Thread类与实现java.lang.Runnable接口。先来看第一种实现方式。
第一步:继承java.lang.Thread;
第二步:重写run方法。
具体过程看以下代码。
public class ThreadTest02{ public static void main(String[] args){ //创建线程(多态:父类型引用指向子类型对象) Thread t=new Processor(); //启动 t.start(); for(int j=0;j<10;j++){ System.out.println("main--->"+j); } }}//自定义一个线程class Processor extends Thread{ //重写run方法 public void run(){ for(int i=0;i<100;i++){ System.out.println("run--->"+i); } }}
继承类java.lang.Thread;方式实现线程主要分为三步,1.自定义一个线程; 2.创建线程; 3.启动线程;
通过下面这张图来看JVM的工作原理。
在上面的代码中,
1.首先自定义线程Processor, 创建线程Thread t=new Processor();属于多态,即父类型引用指向子类型对象。
2.启动线程。t.start(); 这段线程执行瞬间结束,告诉JVM再分配一个栈给t线程。而且run方法不需要程序员手动调用,系统线程启动之后自动调用run方法。
3.以上这个程序有两个线程,一个主线程,一个自定义线程。有了多线程之后,main方法结束只是主线程栈中没有方法栈帧了。但是其他栈中还有栈帧。main方法结束,程序可能还在执行。
4.如果只是使用普通方法调用run方法,即t.run(); 则只有一个线程,run方法只要还没结束,紧跟着的for循环就不会执行。
原文地址:https://www.cnblogs.com/naihuangbao/p/9444323.html