没有多好的开场,只要充分的知识.
1.多线程
之前我们编写的java程序,都是单线程编程,即从主线程(Main线程)开始执行程序,依次执行每行代码,直到程序结束。
单线程的特点是在程序运行中,只有一条线程工作,而在实际应用中,往往单线程是无法满足业务的需求。
比如之前我们学习网络编程,一个客户端对应一个服务端进行通信,但是在实际应用中,是多个客户端对应一个服务端进行通信。那么服务端就需要同时为多个客户端提供通信服务,单个线程就显得力不从心。
Java支持多线程,并提供了非常简单的方式来实现多线程开发,在本章课程中,我们会学习到java线程方面的内容,包括创建、启动线程、控制线程、线程同步、线程通信等等内容。
2.线程和进程的概述
2.1 进程
什么是进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。
(在windows系统 ctrl+shift+esc 、ctrl+alt+delete/. 打开任务管理器可以查看进程)
2.1.1 进程的特征
1、独立性,进程在系统中是独立存在的实体,拥有自己独立的资源,每个进程都有自己私有的地址空间。没有经过程序的允许,其他进程是无法访问该进程所占内存中的数据。如:java虚拟机运行时,是一个进程。
2、动态性:进程与程序的区别在于,程序只是一个静态的指令集合,进程是正在系统中活跃的指令集合,在进程中加入时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中是不具备的。
3、并发性:多个进程可以在单个处理器上并发执行,多个进程之间互不影响(处理器飞速的在多个进程之间跳转)。
2.2 线程
什么是线程:线程是进程的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程,也就是说进程中可以有多个线程,这个应用程序也可以称为多线程程序。
那什么是多线程呢?就是一个程序中有多个线程再执行。
通过下图就可以区分多线程和单线程的区别:
单线程:有多个任务只能一次进行。
多线程:有多个任务可以同时进行。
总结:一个程序运行时候至少有一个进程,一个进程里包含多个线程,最少包含一个。
3.线程的创建方式
3.1 继承Thread类创建线程类
3.1.1 步骤
1、继承Thread类重写run()方法。
2、创建Thread子类实
线程的创建方式
例,即创建线程对象。
3、调用线程对象的start()方法。
启动线程并不是直接调用run方法,而是调用start方法来启动,启动成功后,启动了的这个线程将会与主线程交替执行,就是说,两个线程同时运行,这一刻thread1线程运行,下一刻main主线程运行!
启动线程后,同时运行多个线程,多个线程会抢CPU执行权,谁抢到,谁执行,其他线程挂起。
每一个 Java 线程都有一个优先级,这样有助于操作系统确定线程的调度顺序。
Java 线程的优先级是一个整数,其取值范围是 1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )。
默认情况下,每一个线程都会分配一个优先级 NORM_PRIORITY(5)。
具有较高优先级的线程对程序更重要,并且应该在低优先级的线程之前分配处理器资源。但是,线程优先级不能保证线程执行的顺序,而且非常依赖于平台。
代码演示:
从运行的结果我们看出,并没有任何规律。
注意:不要调用线程对象的run方法启动线程,一定要通过start方法启动线程。直接调用run方法就是是普通调用实例方法调用,不会启动线程。
开启线程,必须调用线程对象的start方法,启动线程,执行run方法代码。
Thread提供一个currentThread方法,可以获取当前执行的线程对象。
每个线程都有线程的名字,比如住线程名称:main。如果自己定义的线程,没有指定线程名,默认为Thread-0~n。
当然可以改变线程的名字,setName(),改变线程名称。也可以通过父类构造器传参,给线程设置线程名
每个线程都有线程的名字,比如住线程名称:main。如果自己定义的线程,没有指定线程名,默认为Thread-0~n。
当然可以改变线程的名字,setName(),改变线程名称。也可以通过父类构造器传参,给线程设置线程名
3.2 实现Runnable接口创建线程
3.2.1 步骤
1、 定义Runnable接口实现类,重写run方法。
2、 创建Runnable实现类实例对象,创建Thread类型对象,将Runnable实例对象传入到Thread对象的构造器中。
Runnable实例对象仅仅作为Thread对象的构造器传入的参数Runnable实现类包含的run方法仅仅作为线程的执行体。而实际的线程对象依然是Thread实例,只是 Thread线程负责执行runnable接口实例对象的run方法,我们翻看源码会发现,其实Thread类就是Runnable的实现类。
因为java是单继承,多实现,所以为了方便扩展,我们一般使用Runnable接口方式实现多线程。
3、调用线程对象的start()方法来启动该线程。
3.3 两种创建接口方式优缺点分析
继承Thread类,具有一定的局限性,因为java体系是单继承,多实现,如果线程对象继承了Thread类,就不可以有其他父类了。
实现Runnable接口,线程对象可以继承其他父类,而且java中接口是多实现的,所以使用该方式,扩展性更好。