Java - 多线程的使用

在学习多线程之前,我们先来明白几个概念。

进程:广义上讲,进程指的是正在运行的程序。比如:QQ、迅雷等。确切的说,进程是一个程序进入了内存,并且处于运行的状态的程序,是一个进行时。

线程:线程是进程中的执行单元,负责当前进程中程序的执行。一个进程至少有一个线程。当一个进程有多个线程的时候,就是我们所说的多线程程序。简单的说:一个程序至少有一个进程,一个进程可以包含多个线程。

程序运行的机制:分时调度和抢占式调度。

分时调度:所有的线程轮流使用 CPU 的使用权,平均分配 CPU 的占用时间。

抢占式调度:根据线程的优先级去分配 CPU 的使用权。

下面我们来学习具体的代码操作:

线程的两种创建方式

1、继承 Thread 类

实现步骤:
1、自定义线程类继承自 Thread
2、重写 run 方法
3、创建自定义线程类
4、调用 start() 方法,jvm 会去调用 run 方法

2、实现 Runnable 接口

实现步骤:
1、自定义线程类实现自 Runnable
2、重写 run 方法
3、创建一个Thread线程对象,将 自定义线程类对象 通过构造传入
4、调用创建的 Thread 对象的 start 方法

既然有两种实现方式,那我们开发中怎么选择呢?

个人更倾向于 Runnable 接口的方式,有如下好处:

1、Java中只允许类的单继承,这避免了这个尴尬
2、更符合面向对象的思想,将线程对象 和 线程任务 分开,高内聚,低耦合。

多线程的栈内存

与单线程程序不同,多线程中,当程序开启一个线程的时候,在栈内存中,每一个执行线程都有自己的一块栈内存空间,进行方法的压栈弹栈。
这里写图片描述

线程状态图

新建、运行、死亡、阻塞、休眠、等待
这里写图片描述

在实际开发中,当需要多个线程时,如果我们一个个去创建会消耗大量的资源。考虑到这点,JDK1.5 之后,Java 就内置了一个线程池。通常,线程池都是通过线程池工厂创建,在调用线程池中的方法获取线程,再通过线程去执行任务方法。

线程池的简单使用:通过 Executors 工厂类,newXXX 创建相应的线程池对象。通过得到的线程池对象调用 submit() 方法提交线程任务。最后不用线程池时,可以 shutdown 掉。 注意:源码底层是调用的 ThreadPoolExecutor 类,这里不深究。

注意,在 submit 提交任务时,可以选择 Runnable 或者 Callable 接口。 Runnable run 方法无返回值,不能抛出异常; Callable call 方法 有返回值,可以抛出异常。注意:Callable call 方法的返回值,即便在 main 主线程调用,也要等到获取到返回值的时候。

相关API

Executors:线程池创建工厂类
public static ExecutorService newFixedThreadPool(int nThreads):返回线程池对象
ExecutorService:线程池接口
Future

猜你喜欢

转载自blog.csdn.net/FresherHe/article/details/82659699
今日推荐