黑马程序员--多线程基础知识

来源:互联网 发布:映射网络驱动器 编辑:程序博客网 时间:2024/06/14 08:08

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


第三讲  多线程基础知识

一、     进程和线程的相关概念

1、进程和线程

进程是正在执行的程序,是系统进行资源分配和调用的独立单元,每一个进程都有自己内存空间和系统资源。如QQ、酷狗音乐等都属于一个进程。

线程是进程中的单个顺序控制流,是一条执行路径。一个进程如果只有一条执行路径,则称为单线程程序。一个进程如果有多条执行路径,则称为多线程程序。如扫雷游戏中的计时、游戏等都是这个进程中的线程。

2、并行和并发

并行是逻辑上的同时发生,指在某一时间内同时运行多个程序。

并发是物理上的同时发生,指在某一时间点同时运行多个程序。

3、线程调度

假如我们的计算机只有一个CPU,那么CPU在某一时刻只能执行一条指令。线程只有得到CPU时间片,也就是使用权,才可以执行指令。线程有两种调度模型:

  • 分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片
  • 抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多些
      Java使用的是抢占式调度模型

二、     Java程序的运行原理

由Java命令启动JVM,JVM启动就相当于启动了一个进程。接着由该进程创建了一个主线程去调用main方法。值得注意的是,JVM虚拟机也是多线程程序,原因是垃圾回收线程也要先启动,否则很容易出现内存溢出。垃圾回收器线程加上主线程,最低启动了两个线程所以JVM虚拟机是多线程程序。

三、     多线程的实现方案

由于线程是依赖进程而存在的,所以我们应该先创建一个进程出来。而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。Java是不能直接调用系统功能的,所以我们没有办法直接实现多线程程序。但是Java可以去调用C/C++写好的程序来实现多线程程序,由C/C++去调用系统功能创建进程,然后由Java调用。然后提供一些类供我们使用

1、  实现方案一

继承Thread类,此方法实现多线程分为以下几个步骤:

A:自定义MyThrdad类继承Thrdad类。

B:MyThrdad类中重写run()。

C:创建对象

D:启动线程

下面是代码实现

  • 为什么要重写run()方法

因为不是类中的所有代码都需要被线程执行,为了区分哪些代码能够被线程执行,Java提供了Thread类中的run()用来包含那些被线程执行的代码。

  • 启动线程使用的是哪个方法run()和start()方法的区别

启动线程用的方法是start(),因为run()直接调用其实就相当于普通的方法调用,所以运行时看到的是单线程的效果,想要看到多线程的效果就要调用start()

  • run()和start()方法的区别

run()仅仅是封装被线程执行的代码,直接调用是普通方法。start()首先启动了线程,然后再由JVM去调用该线程的run()

2、  方案一的基本方法

  • public  final  void  setName(String  name):设置线程的名称
              public  final  String  getName():获取线程的名称

        public  Thread(String  name):带参构造方法
        public  static  Thread  currentThread():返回当前正在执行的线程对象
        Public  final  int  getPriority():获取优先级
        Public  final  void  setPriority(int  newPriority):设置优先级

  • public  static  void  sleep(long  millis):线程休眠,即调用此方法的线程启动执行一次后停顿一段时间再开始执行下一次
       public  final  void  join():等待该线程终止,即调用此方法的线程结束后,其他线程才开始执行。注意必须先启动线程,才可以调用此方法
       public  static  void  yield():线程礼让,调用此方法的线程能够在一程度上均衡CPU的执行权,但不能保证,仍然是随机的
       public  final  void  setDaemon(boolean on):守护线程(后台线程),调用此方法的线程在主线程执行结束后自动停止执行,但是可能有一部分缓冲执行
       public  void  interrupt():
       public  final  void  stop():(已过时)中断线程
3、  实现方案二

实现Runnable接口,此方法实现多线程分为以下几个步骤:

A:自定义MyRunnable类实现Runnable接口。

B:MyRunnable类中重写run()。

C:创建MyRunnable类的对象

D:创建Thread类的对象,将MyRunnable类的对象作为参数传递

下面是代码实现

4、  实现一和实现二的区别

  • 可以避免由于Java单继承带来的局限性。如果想要实现多线程的类已经继承了一个父类,很显然他就无法继承Thread类,此时实现Runnable接口可以是这个类实现多线程
  • 适合多个相同程序的代码去处理同一个资源的情况,例如MyThread类的成员变量如果较多的话,使用继承Thread类来实现多线程是,每一个线程都要创建MyThread类的对象(包括其中的成员变量),而实现Runnable接口只需要创建一个MyRunnable类的对象,将此对象作为参数传递即可。这样把线程同程序的代码、数据分离,较好的体现了面向对象的设计思想。

四、     线程的生命周期


0 0
原创粉丝点击