快速理解进程和多线程,如何创建多线程。

本文深入解析进程、线程和多线程概念,探讨多线程优势、应用场景,讲解单线程与多线程的区别,CPU切换原理,以及如何通过无锁机制和线程池优化并发。最后介绍多线程创建方式和实战示例,包括Spring异步注解的使用。
摘要由CSDN通过智能技术生成

一.什么是进程

当我们启动一个应用程序,就会开启一个进程。

win:任务管理器

linux:ps kill-9

在进程中至少有一条线程,该线程就是主线程。

进程就是我们所有线程的的集合。

二.什么是线程

线程就是一条程序的执行路径。

在进程中开启一条线程执行我们的程序代码,程序的执行顺序必须遵循从上往下的顺序。

注意:如果是多线程的情况下,代码的执行顺序就是从上往下执行。

三.什么是多线程

也就是再同一个进程中开启了多条不同的执行路径,每条执行路径相互不影响,同时执行。

四.多线程有哪些好处

能够帮助我们实现提高程序的效率,是同时的并行的。

五.多线程哪些应用场景。

1.异步的实现发送短信,快速提高相应,对用户的体验非常好。

2.异步的实现记录日志。

3.支付中异步的回调。

4..对我们后端接口中比较耗时的代码都可以采用异步实现

都是同一个思想:能够快速提高http协议的实现。

http属于同步 (请求request) 响应 Response

六.后端开发为什么需要使用多线程

因为我们http协议默认都是采用同步形式, 整个过程都是基于请求与响应过程, 
如果服务器端没有及时的响应客户端的情况下,就会造成浏览器或者客户端一直等待,这样就对用户体验是非常的不友好。

七.单线程和多线程有哪些区别

单线程的代码执行顺序就是从上往下执行,如果中间环节一旦出错,整个程序中断操作。

整个代码的执行顺序偏低。

//单线程 login() { //查询数据库 findDbLogin(userName.pwd); -2s //记录登录日志 login(log); --2s //发送邮件 sendEmail(emali); --2s //发送短信 sendSms(phone) -2s }

总共需要8s完成

多线程:采用多条不同的线程执行程序,每个线程之间互不影响。不同的路径可以提高程序的效率

八.如何理解CPU切换线程的概念


对于如果使用单核CPU服务器,开启多线程的情况下,并不能够真正意义的的多线程, 因为单核CPU服务器在同一时间,最多只能运行一个线程,当正在运行的线程快速切换到另外的一个线程执行,这个过程可以称为CPU切换。

如果是多核处理器,比如i7 8700K处理器 6核12 线程,相当于在于同一时刻可以支持12线程同时访问。如果服务核数越多,对应的线程越多,可以减少cpu切换。



注意:如果我们的在使用单核处理器,并不是真正意义的多线程,底层CPU会不断的切换,切换的过程认为感知好像是多线程。



专门服务器,16核,32线程,32核 64线程

 

九.并发编程如何优化减少Cpu切换线程。

1.无锁机制。2.优化硬件。3.少用线程。

 

十.多线程真的是越多越好吗?

如果在服务器上频繁的开启线程的情况下 ,会导致cpu不断的切换, 会影响服务器的性能。

如果项目比较小的情况下, 可以采用多线程实现异步。如果项目比较大的情况建议使用MQ实现异步。

注意:如果高并发的项目建议使用MQ替代多线程。

 

十一.多线程有哪些创建方式

 

(1)集成Thead类重写Run方法。

package com.company;

/**
 * @Author :guohuan
 * @Description:集成Thead类重写Run方法
 * @Date :2020/9/14 14:36
 */
public class Thread001 extends java.lang.Thread {
    /**
     * 在run方法中写线程需要执行的代码
     */
    @Override
    public void run() {
        System.out.println(Thread001.currentThread().getName() + ",我是子线程");
    }

    public static void main(String[] args) {
        System.out.println(Thread001.currentThread().getName() + ",我是主线程");
        new Thread001().start();
    }

}

(2)实现Runnable接口

package com.company;

/**
 * @Author :guohuan
 * @Description:实现Runnable接口
 * @Date :2020/9/14 14:36
 */
public class Thread002 implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + ",我是子线程");
    }

    public static void main(String[] args) {
        new Thread(new Thread002()).start();
        //写法一
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + ",我是子线程");
            }
        }).start();
        //写法二 拉姆达表达式
        new Thread(() -> System.out.println(Thread.currentThread().getName() + ",我是主线程")).start();
    }

}

(3)实现可以带返回结果线程 Callable

采用异步的去执行线程,但是如果需要获取到该线程执行的结果的情况下,整个过程就变成了一个线程。

package com.company;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @Author :guohuan
 * @Description:实现可以带返回结果线程 Callable
 * @Date :2020/9/14 14:56
 */
public class MyCallback implements Callable<String> {
    @Override
    public String call() throws Exception {

        try {
            System.out.println(Thread.currentThread().getName() + ",正在开始异步发送短信");
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "异步执行发送短信";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //可以获取当前线程返回的结果
        FutureTask<String> futureTask = new FutureTask<>(new MyCallback());
        new Thread(futureTask).start();
        //等待线程执行完毕获取结果
        System.out.println("result:" + futureTask.get());
    }
}

(4) 线程池核心思想 复用线程、管理线程、统一创建和销毁四种实现。

可缓存、可定长度、可定时、单例

package com.company;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author :guohuan
 * @Description:线程池
 * @Date :2020/9/14 15:28
 */
public class Thread003 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(() -> System.out.println(Thread.currentThread().getName() + ",我是线程池"));
    }
}

(5)Spring 提供的异步注解@Async Spring异步问题,代理模式实现。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

窜天猴儿~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值