关于线程的那些事……

云中志

共 2512字,需浏览 6分钟

 ·

2021-11-14 12:15

前言

从今天开始我们要再次重新学习多线程的相关内容,至于为什么要学习多线程,原因很简单,java是一门流行的web端开发语言,而web应用中有一个核心的要素就是效率,也就是快速响应用户的需求,但是随着业务的不断发展,业务环境的复杂化,单一流程的应用很难满足高效率的需求,所以多线程就有了用武之地。

线程

基本知识点

什么是线程

线程是进程中独立运行的子任务,也是程序运行的最小单位。通常情况下,一个进程可以包括多个线程。如果你有仔细观察过电脑任务管理的详细信息的话,你一定对下面这张图片不陌生:

从这张图中我们可以看出计算机的进程数、线程数等数据,这里的线程数就包括java软件运行时的线程,另外,我们从这张图还可以看出来,线程数远远大于进程数,这也从侧面佐证了一个进程可以包含多个线程。

串行与并行

说到多线程就避不过串行和并行的话题,串行就是程序的每一行代码依次执行,在大多数的场景下,后面执行的代码,要依托于前面代码的执行结果,或者说是后面的代码必须在前面的代码执行完成之后才能被执行;而并行就是代码直接没有任何依赖关系,代码与代码之间也没有任何的运行顺序,两段代码可以同时运行,当然,这样说虽然也不完全对,但也算说清楚了并行与串行的应用场景。

说了这么多,下面我们说一些干货:

  • 串行就是我们常说的单线程,必须按照指定的顺序运行,所以效率低下,但同时却可以确保顺序
  • 并行就是我们常说的多线程,线程与线程之间的执行是没有顺序可言的,所以会存在线程安全问题,但是效率比较高

举一个很形象的例子来说明并行和串行,假设你有十件事需要做,按照串行的方式的话,你必须得一件一件地做事,一件事没有完成的时候,是不可以进行下一件事的;按照并行逻辑的话,你可以同时做这十件事,只要你有时间,你就可以选择任意一件事来做,当然如果你要是会分身术的话,那就叫真并发运行了(这就特别类似单核CPU和多核CPU,单核的时候只能来回切换以提高利用效率,多核的时候就真的可以同时运行多个任务)

创建方式

关于线程的创建方式有三种,一种是直接通过继承Thread类的方式。

Thread

这也是最原始的创建方式:

public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("run 方法开始执行了");
    }

    public static void main(String[] args) {
        new MyThread().start();
    }
}

这种方式的缺点很明显,因为在java中,一个类只能继承一个类,所以如果一个类已经继承了父类,它就再没办法通过继承Thread来实现多线程了,于是就有了第二种方式——Runnable接口

Runnable

runnable接口就比Thread类要灵活的多,因为java的接口是运行多实现的,所以一个类实现了其他接口以后,依然可以实现Runnable接口:

public class RunnableDemo extends Observable implements Runnable {
    @Override
    public void run() {
        System.out.println("我是继承了Thread,并实现了Runnable的类");
    }

    public static void main(String[] args) {
        new Thread(new RunnableDemo()).start();
    }
}

但是runnable本身是没法靠自己启动的,它必须通过Thread或者线程池来启动,如果直接调用run方法,也只能是像普通方法一样执行。

虽然RunableThread要灵活,它也能实现我们绝大多数的应用场景,但是在某些应用场景下,它也显得很无能为力,比如run方法需要返回值,这时候callable应运而生。

Callable

相比于ThreadRunnableCallable就是小萌新,因为它是JDK1.5才引入的,而前两个是从JDK1.0就已经存在了:

由于比较萌新,所以Callable的运行方式也比较特殊,只能通过线程池启动:

public class CallableDemo implements Callable<String{
    @Override
    public String call() throws Exception {
        return "hello callable";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Future submit = Executors.newSingleThreadExecutor().submit(new CallableDemo());
        String s = submit.get();
        System.out.println(s);
    }
}

结语

单就线程的知识点来说,这块还是比较简单的,大多都是一些基础的概念,但还是要扎实理解其中的一些要点,这里我们做一个简单的梳理:

  • 线程是程序运行的最小单元
  • 线程可以理解为在进程中独立运行的子任务
  • 一个进程可以包含多个线程
  • 多线程的特点是在同一时间执行多个任务
  • 多线程就是通过使用异步技术,提高处理器的利用效率

最后,希望各位小伙伴记住一句话:不要为了使用多线程而使用多线程,要结合实际业务场景分析。好了,今天就到这里吧,各位小伙伴,晚安吧!

- END -


浏览 23
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报