进程是资源分配最小单位,线程是程序执行的最小单位。
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 {@Overridepublic 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{@Overridepublic 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() {@Overridepublic 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);}@Overridepublic 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 {@Autowiredprivate Test01 test01;@RequestMapping("/")@Testpublic void run() {log.info("开始");new Thread(new Runnable() {@Overridepublic void run() {test01.print();}}).start();log.info("结束");}
}@Slf4j
@Component
public class Test01 {@Asyncpublic 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 "系统错误";}}}