• 多线程学习笔记


    1.什么是线程

    进程是资源分配最小单位,线程是程序执行的最小单位。

    2.什么是进程

     cup从硬盘中读取一段程序到内存中,该执行程序的实例就叫做进程

    一个程序如果被cpu多次 读取到内存中,则变成多个独立的进程

     3.为什么进程中还需要线程呢?

    同一个 应用程序中,更好并行处理

    4.并行/串行区别

    串行也就是单线程执行,代码执行效率非常低,

    并行就是多个线程并行执行,效率也较高。

    5.使用多线程一定会提高 效率吗?

    不一定,需要啊cpu调度的算法就是先把前一个任务的cpu上下文(也是就是cpu寄存器和程序计数器)保存起来,然后加载到新任务的上下文到这些寄存器和程序计数器 ,最后再跳到程序计数器新位置 。

    上下文切换就是cpu从执行该线程换到执行另外的线程

    6.多线程创建方式

    1)继承 Thread 类创建线程

    2)实现Runnable接口创建线程

    3)使用匿名内部类的形式创建线程

    4)使用lambada表达式创建线程

    5)使用Callable和 Futrue创建线程

    6)使用线程池列如用Exrcutor框架

    7)spring @Asyn异步注解

     6-1继承 Thread 类创建线程

    1. public class test extends Thread {
    2. @Override
    3. public void run() {
    4. System.out.println(Thread.currentThread().getName()+"这是子线程");
    5. }
    6. public static void main(String[] args) {
    7. System.out.println(Thread.currentThread().getName()+"这是主线程");
    8. new test().start();//运行线程
    9. }
    10. }

    6-2实现Runnable接口创建线程

    1. public class test implements Runnable{
    2. @Override
    3. public void run() {
    4. System.out.println(Thread.currentThread().getName()+"这是子线程");
    5. }
    6. public static void main(String[] args) {
    7. new Thread(new test()).start();
    8. }
    9. }

    6-3使用匿名内部类的形式创建线程

    1. public class test {
    2. public static void main(String[] args) {
    3. new Thread(new Runnable() {
    4. @Override
    5. public void run() {
    6. System.out.println(Thread.currentThread().getName()+"这是子线程");
    7. }
    8. }).start();
    9. }
    10. }

    6-4使用lambada表达式创建线程

    1. public class test {
    2. public static void main(String[] args) {
    3. new Thread(() -> {
    4. System.out.println(Thread.currentThread().getName() + "这是子线程");
    5. }).start();
    6. }
    7. }

    6-5使用Callable和 Futrue创建线程

    使用Callable和Futue线程可以获取到返回结果,底层基于LockSupport

    1. public class test implements Callable {
    2. public static void main(String[] args)throws Exception {
    3. test test = new test();
    4. final FutureTask task = new FutureTask<>(test);
    5. new Thread(task).start();
    6. Integer integer = task.get();
    7. System.out.println(Thread.currentThread().getName()+","+integer);
    8. }
    9. @Override
    10. public Integer call() {
    11. System.out.println(Thread.currentThread()+"开始执行");
    12. try {
    13. Thread.sleep(3000);
    14. } catch (Exception e) {
    15. e.printStackTrace();
    16. }
    17. System.out.println(Thread.currentThread()+"返回1");
    18. return 1;
    19. }
    20. }

    6-6使用线程池列如用Exrcutor框架

    1. import java.util.concurrent.ExecutorService;
    2. import java.util.concurrent.Executors;
    3. public class Test {
    4. public static void main(String[] args) {
    5. ExecutorService executorService = Executors.newCachedThreadPool();
    6. executorService.execute(() -> {
    7. System.out.println(Thread.currentThread() + "我是子线程");
    8. });
    9. executorService.shutdown();
    10. }
    11. }

     6-7spring @Asyn异步注解结合线程

    这个注解不能用test方法来测试,因为test方法底层是static方法,下面我是用controller来测试

    一定要在在启动类添加@EnableAsync //开启异常注解

    1. */
    2. @Slf4j
    3. @RestController
    4. public class Test02 {
    5. @Autowired
    6. private Test01 test01;
    7. @RequestMapping("/")
    8. @Test
    9. public void run() {
    10. log.info("开始");
    11. new Thread(new Runnable() {
    12. @Override
    13. public void run() {
    14. test01.print();
    15. }
    16. }).start();
    17. log.info("结束");
    18. }
    19. }
    20. @Slf4j
    21. @Component
    22. public class Test01 {
    23. @Async
    24. public void print() {
    25. try {
    26. Thread.sleep(3000);
    27. log.info("异常");
    28. } catch (InterruptedException e) {
    29. e.printStackTrace();
    30. }
    31. }
    32. }

     7.手写@Asyn异步注解

    1. import java.lang.annotation.*;
    2. @Target({ElementType.TYPE, ElementType.METHOD})
    3. @Retention(RetentionPolicy.RUNTIME)
    4. @Documented
    5. public @interface Async {
    6. String value() default "";
    7. }

    添加aop,看触发情况

    1. package com.example.list.controller;
    2. import lombok.extern.slf4j.Slf4j;
    3. import org.aspectj.lang.ProceedingJoinPoint;
    4. import org.aspectj.lang.annotation.Around;
    5. import org.aspectj.lang.annotation.Aspect;
    6. import org.springframework.stereotype.Component;
    7. @Slf4j
    8. @Aspect
    9. @Component
    10. public class ExThreadAop {
    11. /**
    12. * 环绕通知
    13. */
    14. @Around(value = "@annotation(com.example.list.controller.Async)")
    15. public Object around(ProceedingJoinPoint joinPoint) {
    16. try {
    17. log.info("环绕通知开始执行......");
    18. joinPoint.proceed();
    19. return "环绕通知";
    20. } catch (Throwable throwable) {
    21. return "系统错误";
    22. }
    23. }
    24. }

  • 相关阅读:
    第10/100天 阅读笔记
    数据分析笔试题(二)
    Django系列8-员工管理系统实战--部门管理
    常用ORM框架:Hibernate与MyBatis
    RabbitMQ常用命令
    Visual Interpretability for Deep Learning: a Survey
    【编译原理】-- 第二章(一)(文法和语言的定义、递归规则与递归文法、例题)
    引用——C++
    【深度学习实验】网络优化与正则化(五):数据预处理详解——标准化、归一化、白化、去除异常值、处理缺失值
    Java项目:ssm毕业论文管理系统
  • 原文地址:https://blog.csdn.net/qq_42847719/article/details/128187829