线程,进程以及Java中创建线程的多种方式

1. 前言

今天的这篇文章的目的还是为了讲述下什么叫线程,什么是进程。可能之前很多人都是通过背书得来的,今天就从通俗易懂的角度来分析下

2. 适合人群

  • 线程以及进程的初学者

3. 开始

3.1 什么是程序

  1. 其实不管是程序/ 进程/ 线程都是基于操作系统而言的。
  2. 对于操作系统而言的话,程序就是一个后缀为exe或是msi的可执行文件,当我们点击执行文件的时候,会将文件内容加载到操作系统的内存中,同时也是开辟一块空间来保存执行文件
  3. 程序好比一个js文件,操作系统好比是浏览器。一个执行以及被执行的关系

在这里插入图片描述

3.2 什么是进程

先来揭晓下答案:进度是资源分配的最小单位

其实并不是把执行文件加载到内存总就完事了,而是会安排进程进行资源分配。比如分配端口号,网络等。所以进程是资源分配的最小单位

3.3. 什么是线程

先揭晓答案:线程是调度执行的最小单位

虽然已经将程序加载到内存中了,同时也是给程序分配资源来,但是并不是靠进程来执行。 其实我们还是靠主线程来执行程序的

所以其实可以理解为线程就是一条执行路径。可能一个事情的完成需要多个线程来完成。这就是所谓的多线程

在这里插入图片描述
在这里插入图片描述

3.4 QA

解释下面的问题的时候,我们需要知道什么是CPU密集型处理。 就是完成功能的大部分处理是需要CPU来完成的,比如计算等。当然IO 相关的不算啊。

3.4.1 单核CPU设置多线程有意义吗

  • 在某种程度上是有意义的
  • 场景1:如果用户多个任务都是需要密集型计算的话,那么对于单核CPU而言的话,只能一个一个执行了。因为所有的计算都依赖此唯一的CPU来完成。这种其实多线程没有意义
  • 场景2:同样用户需要完成多个任务,但是一个任务等待IO输入输出的,一个任务是CPU密集型的。这个时候其实一个线程等待外部设备输入交互。另一个线程来进行计算。通过系统控制线程切换来完成。 这种情况下 是存在意义的

3.4.2 一定是线程越多越好吗

我们使用遍历10亿的数字来做一个实验,看看是不是线程开辟越多越好呢

  • 通过单线程来执行
    在这里插入图片描述
  • 通过多线程来执行

在这里插入图片描述

通过上述实例得知,并不是线程开辟越多越好的。因为线程的切换同样需要时间。但是最合适的办法是经过不断的压测来得出结论才是最真实的

3.4.3 有没有啥公式可以套用呢???

还真有,虽然套用的公式也是前人经过无数次的实验总结的,但是个人还是感觉应该经过自己压测实践最好了。不过公式该给出还是应该给出的

在这里插入图片描述

3.5 创建线程的多种方式

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("这是创建线程的一种方式:通过继承来实现");
    }
}

class MyRun implements Runnable {
    @Override
    public void run() {
        System.out.println("这是创建线程的一种方式:通过实现接口来实现");
    }
}

class MyCall implements Callable<String> {

    @Override
    public String call() throws Exception {
        System.out.println("这是创建线程的一种方式:通过实现接口Callable来完成");
        return "success";
    }
}

public class Thread_02_CreateThread {

    @Test
    public void test() throws ExecutionException, InterruptedException {
        // 线程的创建方式1
        new MyThread().start();
        // 线程的创建方式2
        new Thread(new MyRun()).start();
        // 线程的创建方式3
        new Thread(() -> {
            System.out.println("这是创建线程的一种方式:通过lambda表达式创建");
        }).start();
        // 线程的创建方式4
        FutureTask<String> futureTask = new FutureTask<>(new MyCall());
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println(futureTask.get());

        // 线程的创建方式 5
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(() -> {
            System.out.println("这是创建线程的一种方式:通过线程池来进行创建");
        });

        Future<String> submit = executorService.submit(new MyCall());
        System.out.println(submit.get());
        executorService.shutdown();
    }

上述代码是Java中创建线程的几种方式

3.5.1 继承ThreadRunnable 哪个好呢???

  • 总体而言的话是Runnable 会更好点。因为在Java中是单继承,多实现。如果我们开发中继承了Thread就不能继承别的类的。但是我们可以实现多个接口
  • 可能唯一有遗憾的就是 这些继承或是接口 都是没有返回值的

3.5.2 如果想要返回值呢???

如果想线程有返回值的话,可以继承接口Callable 来指定返回值

3.5.3 如果想写法简单点呢???

如果只是想在线程内做一些操作的话,对返回值无要求,同时想要写法简单点,可以使用上述代码中的lambda来完成线程的创建

4. 结束

以上是对程序/ 线程/ 进程的理解。以及在Java中创建线程的几种方式。源码请参照. 如果大家觉得对自己有用处的话,希望大家点赞,收藏。多多关注小编哦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值