JAVA多线程基础篇(一)

1.概述

在学习java多线程之前,首先需要了解进程和线程的概念,具体阐述如下:
(1)进程
指的是一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间。例如在windows程序中,一个.exe程序就是一个进程。
(2)线程
线程在进程下行进,一个进程至少有一个线程,不同进程之间资源难以共享,同一进程下不同线程可以进行数据共享。
(3)进程与线程区别
进程与进程之间一般不会相互影响,但线程的运行会影响其父进程,一旦某个线程挂掉,可能会影响整个进程。

2.多线程原理

(1)一个简单的多线程例子
在这里插入图片描述
在这里插入图片描述
(2)案例运行结果
在这里插入图片描述在这里插入图片描述在这里插入图片描述
(3)流程分析
在这里插入图片描述
当程序启动时,首先运行main,此时的java虚拟机启动了一个进程,主线程main在main()方法执行的时候被创建。随着调用myThread.start()方法,创建并启动了另一个线程,整个应用便在多线程下运行。
(4)原理分析
(a)调用run方法原理图
main方法运行时,首先会创建对象MyThread,并将所创建对象的地址值给myThread变量。此时main方法中的代码会压栈,当调用myThread的run方法时,run方法也会被压栈,所以,调用run方法并非是多线程,还是在main线程里进行运行,没有创建新线程。
在这里插入图片描述
(b)调用start方法原理图
程序启动运行main的时候,java虚拟机启动一个线程,主线程main在main()方法调用的时候被创建,在调用myThread的start方法时,另一个线程也被创建启动,执行run方法,当执行线程的任务结束了,线程自动在栈内释放,所有线程结束,那么进程也就结束了。
在这里插入图片描述

3.创建多线程的三种方式

(1)继承Thread
主要包含以下步骤:
(a)首先继承Thread类;
(b)重写Thread类中的run方法;
(c)调用start方法。
(2)实现Runable接口
主要包含以下步骤:
(a)定义Runnable接口的实现类;
(b)重写接口中的run方法;
(c)创建Runnable实现类的实例,并以此作为Thread的target来创建Thread对象,该Thread才是真正的线程对象;
(d)调用线程对象的start()方法来启动线程。
(e)代码如下:
在这里插入图片描述在这里插入图片描述
(3)第三种实现方式
通过 Callable 和 FutureTask 创建线程,这种方式可以获取线程运行后的返回结果。实现步骤:
(a)创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
(b)创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
(c)使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
(d)调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
在这里插入图片描述
在这里插入图片描述
(4)三种实现方式的区别
如果一个类继承Thread,则不适合资源共享,但是如果实现了Runable接口,则很容易实现资源共享。
总结:
实现Runable接口比继承Thread具有更大优势:
(a)继承具有单一性和局限性
一个类只能继承一个类,类继承了Thread类就不能继承其它的类;如果实现Runable类,还可以继承其它类。
(b)增强了程序的可扩展性,降低了程序的耦合性。
实现Runable接口的方式,把设置线程任务和开启线程进行了分离解耦。
(c)增加程序的健壮性,代码可以被多个线程共享。
(d)如果需要获取线程运行后的返回结果,则需要使用callable和future来创建线程。

(5)匿名内部类实现
使用线程的匿名内部类,可以方便地实现每个线程执行不同的线程任务操作,但可能会使得代码的可读性相对较差,建议根据场景需要使用。

猜你喜欢

转载自blog.csdn.net/qq_33479841/article/details/107029923