进程是资源分配最小单位,线程是程序执行的最小单位。
cup从硬盘中读取一段程序到内存中,该执行程序的实例就叫做进程
一个程序如果被cpu多次 读取到内存中,则变成多个独立的进程
同一个 应用程序中,更好并行处理
串行也就是单线程执行,代码执行效率非常低,
并行就是多个线程并行执行,效率也较高。
不一定,需要啊cpu调度的算法就是先把前一个任务的cpu上下文(也是就是cpu寄存器和程序计数器)保存起来,然后加载到新任务的上下文到这些寄存器和程序计数器 ,最后再跳到程序计数器新位置 。
上下文切换就是cpu从执行该线程换到执行另外的线程
1)继承 Thread 类创建线程
2)实现Runnable接口创建线程
3)使用匿名内部类的形式创建线程
4)使用lambada表达式创建线程
5)使用Callable和 Futrue创建线程
6)使用线程池列如用Exrcutor框架
7)spring @Asyn异步注解
6-1继承 Thread 类创建线程
- public class test extends Thread {
- @Override
- public void run() {
- System.out.println(Thread.currentThread().getName()+"这是子线程");
- }
-
- public static void main(String[] args) {
- System.out.println(Thread.currentThread().getName()+"这是主线程");
- new test().start();//运行线程
- }
- }
6-2实现Runnable接口创建线程
- public class test implements Runnable{
- @Override
- public void run() {
- System.out.println(Thread.currentThread().getName()+"这是子线程");
- }
-
- public static void main(String[] args) {
- new Thread(new test()).start();
- }
- }
6-3使用匿名内部类的形式创建线程
- public class test {
-
-
- public static void main(String[] args) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- System.out.println(Thread.currentThread().getName()+"这是子线程");
- }
- }).start();
- }
- }
6-4使用lambada表达式创建线程
- public class test {
-
-
- public static void main(String[] args) {
- new Thread(() -> {
-
- System.out.println(Thread.currentThread().getName() + "这是子线程");
-
- }).start();
- }
- }
6-5使用Callable和 Futrue创建线程
使用Callable和Futue线程可以获取到返回结果,底层基于LockSupport
- public class test implements Callable
{ -
-
- public static void main(String[] args)throws Exception {
- test test = new test();
- final FutureTask
task = new FutureTask<>(test); - new Thread(task).start();
- Integer integer = task.get();
- System.out.println(Thread.currentThread().getName()+","+integer);
- }
-
- @Override
- public Integer call() {
- System.out.println(Thread.currentThread()+"开始执行");
- try {
- Thread.sleep(3000);
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread()+"返回1");
- return 1;
- }
- }
6-6使用线程池列如用Exrcutor框架
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
-
- public class Test {
- public static void main(String[] args) {
- ExecutorService executorService = Executors.newCachedThreadPool();
- executorService.execute(() -> {
- System.out.println(Thread.currentThread() + "我是子线程");
-
- });
- executorService.shutdown();
-
- }
- }
6-7spring @Asyn异步注解结合线程
这个注解不能用test方法来测试,因为test方法底层是static方法,下面我是用controller来测试
一定要在在启动类添加@EnableAsync //开启异常注解
- */
- @Slf4j
- @RestController
- public class Test02 {
- @Autowired
- private Test01 test01;
-
- @RequestMapping("/")
- @Test
- public void run() {
- log.info("开始");
- new Thread(new Runnable() {
- @Override
- public void run() {
- test01.print();
- }
- }).start();
- log.info("结束");
- }
- }
-
-
- @Slf4j
- @Component
- public class Test01 {
- @Async
- public void print() {
- try {
- Thread.sleep(3000);
- log.info("异常");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- }
-
-
- }
- import java.lang.annotation.*;
-
- @Target({ElementType.TYPE, ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface Async {
- String value() default "";
- }
添加aop,看触发情况
- package com.example.list.controller;
-
-
- import lombok.extern.slf4j.Slf4j;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.springframework.stereotype.Component;
-
- @Slf4j
- @Aspect
- @Component
- public class ExThreadAop {
-
- /**
- * 环绕通知
- */
- @Around(value = "@annotation(com.example.list.controller.Async)")
- public Object around(ProceedingJoinPoint joinPoint) {
- try {
- log.info("环绕通知开始执行......");
- joinPoint.proceed();
- return "环绕通知";
- } catch (Throwable throwable) {
- return "系统错误";
- }
- }
-
- }