多线程

来源:互联网 发布:阿里云服务器如何重启 编辑:程序博客网 时间:2024/06/05 22:44

进程:

进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。

线程:

线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程

什么是多线程呢?

即就是一个程序中有多个线程在同时执行。

程序运行原理

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

  • 抢占式调度
    优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

该如何创建线程呢?

  • 一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。创建对象,开启线程。run方法相当于其他线程的main方法。
  • 另一种方法是声明一个实现 Runnable 接口的类。该类然后实现 run 方法。然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程。

思考:线程对象调用 run方法和调用start方法区别?
线程对象调用run方法不开启线程。仅是对象调用方法。线程对象调用start开启线程,并让jvm调用run方法在开启的线程中执行。

多线程的内存图解

多线程执行时,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。进行方法的压栈和弹栈。
这里写图片描述
当执行线程的任务结束了,线程自动在栈内存中释放了。但是当所有的执行线程都结束了,那么进程就结束了。

  • Thread.currentThread()获取当前线程对象
  • Thread.currentThread().getName();获取当前线程对象的名称

实现Runnable的好处

实现Runnable接口避免了单继承的局限性,所以较为常用。实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。实现runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。Runnable接口对线程对象和线程任务进行解耦。

线程池概念

线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源

这里写图片描述

使用线程池方式–Runnable接口

通常,线程池都是通过线程池工厂创建,再调用线程池中的方法获取线程,再通过线程去执行任务方法。

  • Executors:线程池创建工厂类
    • public static ExecutorService newFixedThreadPool(int nThreads):返回线程池对象
  • ExecutorService:线程池类
    • Future<\?> submit(Runnable task):获取线程池中的某一个线程对象,并执行
  • Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用

  • 使用线程池中线程对象的步骤:

    • 创建线程池对象
    • 创建Runnable接口子类对象
    • 提交Runnable接口子类对象
    • 关闭线程池

使用线程池方式—Callable接口

  • Callable接口:与Runnable接口功能相似,用来指定线程的任务。其中的call()方法,用来返回线程任务执行完毕后的结果,call方法可抛出异常。
  • ExecutorService:线程池类
    • Future submit(Callable task):获取线程池中的某一个线程对象,并执行线程中的call()方法
  • Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用

  • 使用线程池中线程对象的步骤:

    • 创建线程池对象
    • 创建Callable接口子类对象
    • 提交Callable接口子类对象
    • 关闭线程池
0 0
原创粉丝点击