黑马程序员_多线程(概念和创建)
来源:互联网 发布:mac便签 桌面显示 编辑:程序博客网 时间:2024/05/23 20:42
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
多线程(概念和创建)
一、多线程概念
提到线程,就得提到进程,进程就是正在进行中的程序。但是进程并不是多个程序同步执行他们,而是cpu逐个执行,先执行一个程序,然后执行另一个程序,cpu这是其实是在进行快速切换,只是速度很快,我们看起来像是在同步执行。
线程进程里的东西,理解的来说,比如迅雷中下载一个软件,这个软件通常看到的不是一个整体下载的,而是分成很多压缩包同时在下载,这多个压缩包就会同时向服务端请求数据,这就是线程,整个软件就是进程。这样看来,一个进程里至少含有一个线程。
我们在运行java程序的时候,JVN也开启了一个javaexe的进程,程序中有主函数main,这个主函数中就含有一个线程,我们称之为主线程。之前,所学习的程序,都一直是单线程形式的。
多线程,可以使多个代码同时执行,提高了效率。
总结:
1、 进程是一个正在执行中的程序。每个进程都有一个执行顺序,该顺序是一个执行路径或者控制单元。
2、 线程是进程中的一个独立控制单元。线程在控制着进程的执行。
3、 一个线程至少有一个线程。
4、 多线程可以提高效率。
二、 创建多线程
创建多线程,现在就是在我们自己写的程序中加入多线程。
创建方式1
步骤:1、创建一个类,继承Thread
2、复写Thread中的run方法
3、建立子类对象,调用线程的start方法,该方法有两个作用,一是启动该线程,二是调用run方法。
以我自己的理解来描述:像异常中的自定义异常类,在多线程中,想要在主函数(我们现在常写的程序)中建立一个线程,首先要定义一类继承Thread,这个类必须复写run方法,这两步是必须的。这时线程还没有建立,我们需要在主函数中建立自定义类的对象,通过对象调用start方法,格式为:对象名.start()。此处start方法,建立了一个新的线程,同时调用run方法,这就是我们要复写run方法的原因。
看一下示例程序:
publicclass TestOfJava {
publicstaticvoid main(String[] args) {
Demo d = new Demo();
d.start();
for(int x=0;x<60;x++){
System.out.println("mainrun"+x);
}
}
}
class Demoextends Thread{
publicvoid run(){
for(int x=0;x<60;x++){
System.out.println("Demorun"+x);
}
}
}
看上述程序,就是在主函数中开辟了一个新的线程,start开启新线程,同时调用了run方法。在主函数中,其实有两个线程,一个是主函数的线程,可以称之为主线程。现在又加入一个新线程,此时,这个javaexe进程中就有两个线程了。这两个线程不是同步进行的,可以看上述程序结果,是一会儿执行主线程,一会儿执行自定义线程。而且每次运行结果不一样。因为多个线程都在获取cpu执行权,cpu执行到谁,谁就运行。需要明确的一点是,在某个时刻,只能有一个程序在运行(仅限单cpu情况)。CPU实际上是在做快速切换动作,因为以毫秒计时,所以看上去是同时运行的效果。我们可以形象的把多线程的运行i型能够为看成在互相抢夺CPU执行权。这就是多线程的一个特性:随机性。谁抢到谁执行,至于执行时间多长,cpu来决定。
具体为什么要覆盖run方法?
Thread类用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码,该代码功能就是run方法。也就是说Thread类中的run方法,用于存储线程要运行的代码。
我们创建一个新的线程,就是为了执行我们定义的代码,而start是开启新线程,当我们不覆盖run方法,Thread中的run方法中什么代码都没有,所以不覆盖run方法没有意义;当我们覆盖run方法,在run方法中加入我们要运行的代码,这样新建线程就可以执行我们自己定义的代码。
线程中常用方法:
static Thread currentThread():获取当前线程对象
getName():获取线程名称
setName():设置线程名称。注意:可以再子类中覆盖setName方法,或是在子类构造函数中调用父类构造函数即可。
创建线程总结:
1、 首先自定义线程要继承Thread类,使得其加入java线程体系。
2、 覆盖run方法,在run方法中加入我们要运行的程序。
run方法中,就是要存储我们想要运行的代码,就这个作用。
3、 建立自定义线程类的对象,调用start方法。
我们要在主函数中开启新线程,只有start方法能开启。如果直接调用run或者其他方法,其实这时就没有开启新线程,只是把我们定义的代码执行一遍,其实还是只有一个主线程。
4、 单cpu功能,同一时间只能执行一个程序
5、 多线程的特性就是随机性。
三、线程的五种运行状态
语言描述来说,一个线程继承Thread和复写run方法,然后荣国start方法建立了新线程,创建线程就是一个状态。建立线程后,我们自定义的程序就会运行,运行也是一个状态。当线程运行时,cpu在某一时刻只执行一个程序,那么其他程序就会等待,这就分了两种情况,一是没有运行资格,二是有有运行资格但是没有执行权,前一种称为冻结,简单来说就是放弃了执行资格,这其中也有两种状态,一是sleep(time),就是让程序睡一定的时间,时间到了就会自动唤醒,使得程序具备运行资格;二是wait(),就是让程序等待,只有通过notify()来主动唤醒程序,使得程序有运行资格。有运行资格的程序,也会有两个方向,一是直接运行,二是因为cpu某一时间段只运行一个程序,这些有运行资格但是还没有轮到执行权的程序,就会在另一种状态,称为阻塞状态。最后一种,就是线程执行完毕,就会消亡,消亡也是一状态。看图例:
四、创建线程的第二种方法
方法步骤为:
1、 定义类实现Runnable接口。注意和原来继承Thread不同。
2、 覆盖Runnable接口中的run方法,将线程要运行的代码存放在该run方法中。接口中有一个run方法,我们定义的类中也要吧run方法复写。
3、 通过Thread类建立线程对象。Runnable并不能实现Thread类的功能,只有Thread类的功能才能建立线程。
4、 将Runnable接口的子类对象,最为实际参数传递给Thread类的构造函数。为什么呢?因为,自定义的run方法所属的对象时Runnable接口的子类对象,所哟要让线程去指定指定对象的run方法,就必须明确该run方法所属的对象。
5、 调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
示例程序如下:
classTicket implements Runnable//extendsThread {
public void run(){
}
}
classTestForYou {
public static void main(String[] args){
Ticket t = new Ticket();
Threadt1 = new Thread(t);
t1.start();
}
需要强调的是,一、Runnable接口的子类,没有start方法,不能建立线程而如果光有Thread建立的对象,线程是可以建立的,但是运行的run方法时Thread本身的,对于我们来说没有意义。二、只有Thread的类和其子类可以建立线程,所以才把Runnable接口的子类对象传入,是Thread线程建立时,可以调用我们要运行的run方法。
既然有两个线程建立方式,那么总结一下:
1) 一个是实现方式,一个是继承方式。
2) 实现方式避免了单继承的局限性。因为编程中,我们定义的子类可能会因为需要已经继承了另一个父类,而子类中也有我们需要的同步执行的代码,那么java中单继承规则的存在,使得不能使用直接继承Thread类的方式创建新线程。这就用到了实现方式,实现Runnable接口,间接的增加的程序的拓展性。
3) 在使用上,一般建立线程使用实现方式,因为更有拓展性,接口也可多实现。
4) 注意两者的区别,继承方法中,线程代码存放于Thread子类的run方法中;实现方法中,线程代码存放于Runnable接口子类的run方法中。
5)
- 黑马程序员_多线程(概念和创建)
- 黑马程序员_多线程的创建和运行机制学习笔记
- 黑马程序员_多线程(线程安全和通信)
- 黑马程序员_线程和多线程
- 黑马程序员_单线程和多线程
- 黑马程序员_多线程和String类
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 2 引擎架构
- CRect类 的介绍
- 关于在myeclipse2014里新建一个HTML5版本的html文件,浏览器中文显示乱码的问题
- PythonChallenge 编程游戏-------第2关
- OpenGL离屏渲染
- 黑马程序员_多线程(概念和创建)
- centos中安装gdbm以及编译运行第一个gdbm程序
- 华东理工某ACMer总结
- 4.Maven概念模型,maven的生命周期,Maven坐标,依赖管理(依赖范围,依赖声明),仓库管理,私服概念
- dropbear 安全登录
- c#线程的创建与启动
- iOS获取当前城市
- 业界资讯:下一个版本出啥?
- ListView中实现互斥按钮(每个Item中有两个button,永远只有一个item中的一个按钮被选中)