进程是资源分配最小单位,线程是程序执行的最小单位。
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 "系统错误";
}
}
}