资讯专栏INFORMATION COLUMN

线程总结

justCoding / 1371人阅读

摘要:一个进程可以拥有多个线程,一个线程必须有一个父进程。线程是独立运行的,它并不知道进程中是否还有其他的线程存在。线程的调度和管理由进程本身负责完成。因此多线程实现多任务并发比多线程的效率高。

  一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。

进程
定义:

  当一个程序进入内存运行时,即变成一个进程。进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位。

进程的特点:

独立性:是系统独立存在的实体,拥有自己独立的资源,有自己私有的地址空间。在没有经过进程本身允许的情况下,一个用户的进程不可以直接访问其他进程的地址空间。

动态性:进程与程序的区别在于:程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集和,进程中加入了时间的概念。进程具有自己的生命周期和不同的状态,这些都是程序不具备的。

并发性:多个进程可以在单个处理器上并发执行,多个进程之间不会相互影响。

并行性和并发性

  并行:指在同一时刻,有多条指令在多个处理上同时执行。(多核同时工作)

  并发:指在同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。(单核在工作,单核不停轮询)

线程

  多线程扩展了多进程的概念,使得同一个进程可以同时并发处理多个任务。
  线程(Thread)也被成为轻量级的进程,线程是进程执行的单元,线程在程序中是独立的、并发的执行流

  当进程被初始化后,主线程就被创建了。绝大数应用程序只需要有一个主线程,但也可以在进程内创建多条的线程,每个线程也是相互独立的。

  一个进程可以拥有多个线程,一个线程必须有一个父进程。

  线程可以拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不拥有系统资源,它与父进程的其他线程共享该进程所拥有的全部资源,因此编程更加方便。

  线程是独立运行的,它并不知道进程中是否还有其他的线程存在。线程的执行是抢占式的,即:当前运行的线程在任何时候都有可能被挂起,以便另外一个线程可以运行。

  一个线程可以创建和撤销另一个线程,同一个进程中多个线程之间可以并发执行。

  线程的调度和管理由进程本身负责完成。

  归纳而言:操作系统可以同时执行多个任务,每个任务就是进程;进程可以同时执行多个任务,每个任务就是线程

多线程的优点:

进程之间不能共享内存,但线程之间共享内存非常容易

系统创建进程要为该进程重新分配系统资源,但创建线程的代价则小得多。因此多线程实现多任务并发比多线程的效率高。

Java语言内置了多线程功能支撑,简化了多线程的编程。

线程的创建和启动
一、继承Thread类创建线程类

步骤:
① 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,称为线程执行体

② 创建Thread子类的实例,即创建了线程对象

③ 调用线程对象的start()方法来启动该线程
示例:

// 通过继承Thread类来创建线程类
public class FirstThread extends Thread
{
    private int i ;
    // 重写run方法,run方法的方法体就是线程执行体
    public void run()
    {
        for ( ; i < 100 ; i++ )
        {
            // 当线程类继承Thread类时,直接使用this即可获取当前线程
            // Thread对象的getName()返回当前该线程的名字
            // 因此可以直接调用getName()方法返回当前线程的名
            System.out.println(getName() +  " " + i);
        }
    }
    public static void main(String[] args)
    {
        for (int i = 0; i < 100;  i++)
        {
            // 调用Thread的currentThread方法获取当前线程
            System.out.println(Thread.currentThread().getName() +  " " + i);
            if (i == 20)
            {
                // 创建、并启动第一条线程
                new FirstThread().start();
                // 创建、并启动第二条线程
                new FirstThread().start();
            }
        }
    }
}
注意点:

① 当Java程序开始运行后,程序至少会创建一个主线程,main()方法的方法体代表主线程的线程执行体

② 当线程类继承Tread类时,直接使用this即可以获取当前线程

③ 继承Thread类创建线程类,多个线程之间无法共享线程类的实例变量

二、实现Runnable接口创建线程类
步骤:

① 定义Runnable接口的实现类,并重写该接口的run()方法

② 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Tread对象,该Tread对象才是真正的线程对象

// 通过实现Runnable接口来创建线程类
public class SecondThread implements Runnable
{
    private int i ;

    // run方法同样是线程执行体
    public void run()
    {
        for ( ; i < 100 ; i++ )
        {
            // 当线程类实现Runnable接口时,
            // 如果想获取当前线程,只能用Thread.currentThread()方法。
            System.out.println(Thread.currentThread().getName() + "  " + i);
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100;  i++)
        {
            System.out.println(Thread.currentThread().getName() + "  " + i);
            if (i == 20)
            {
                SecondThread st = new SecondThread();     // ①

                // 通过new Thread(target , name)方法创建新线程
                new Thread(st , "新线程1").start();
                new Thread(st , "新线程2").start();
            }
        }
    }
}
注意点:

① 实现Runnable接口创建线程类,必须通过Thread.currentThread()方法来获得当前线程对象

② 实现Runnable接口创建线程类,多个线程可以共享线程类的实例变量

三、使用Callable和Future创建线程

Callable接口提供了一个call()方法,call()方法比run()方法更强大:
① call()方法可以由返回值

② call()方法可以声明抛出异常

步骤:

① 创建Callable接口的实现类,并实现call()方法,该call()方法作为线程执行体,且该call()方法有返回值

② 使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值

③ 调用FutureTask对象的get()方法获得子线程执行结束的返回值

创建线程三种方式的对比:
实现Runnable接口、Callable接口创建线程

优点:
①实现的是接口,还可以继承其他类

② 多个线程可以共享同一个target对象,适合多个相同的线程来处理同一份资源的情况

缺点:
① 编程稍微复杂

② 获取当前线程必须用Thread.currentThread()方法来获得

继承Tread类创建线程

优点:
①编程简单

② 获取当前线程,可以直接使用this来获得

缺点:
① 已经继承了Thread类,不能继承其他类

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69113.html

相关文章

  • Java线程池简单总结

    摘要:本文主要内容为简单总结中线程池的相关信息。方法簇方法簇用于创建固定线程数的线程池。三种常见线程池的对比上文总结了工具类创建常见线程池的方法,现对三种线程池区别进行比较。 概述 线程可认为是操作系统可调度的最小的程序执行序列,一般作为进程的组成部分,同一进程中多个线程可共享该进程的资源(如内存等)。在单核处理器架构下,操作系统一般使用分时的方式实现多线程;在多核处理器架构下,多个线程能够...

    CoorChice 评论0 收藏0
  • Java 虚拟机总结给面试的你(下)

    摘要:本篇博客主要针对虚拟机的晚期编译优化,内存模型与线程,线程安全与锁优化进行总结,其余部分总结请点击虚拟总结上篇,虚拟机总结中篇。 本篇博客主要针对Java虚拟机的晚期编译优化,Java内存模型与线程,线程安全与锁优化进行总结,其余部分总结请点击Java虚拟总结上篇 ,Java虚拟机总结中篇。 一.晚期运行期优化 即时编译器JIT 即时编译器JIT的作用就是热点代码转换为平台相关的机器码...

    amc 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<