1 场景:
1:执行的任务,短而快。不能是很耗时的任务。
2:异步写日志(日志框架底层就是)。
3:异步发送邮件,短信。 用MQ 最好。
4:多线程下载
2 进程与线程
进程:
进程:
1:cpu从硬盘中读取一段程序到内存中,该执行程序的实例就叫进程。
2:一个程序如果被cpu多次读取到内存中,则变成多个独立的进程
线程:
1:线程是程序执行的最小单位,在一个进程中,可以有多个线程同时执行。
线程:
1:单核的cpu上每次只能够执行一次线程,如果在单核的cpu上开启了多线程,则会发生对每个线程轮流执行,也就是我们说的 (上下文切换)。
2:Cpu每次单个计算的时间称为一个cpu时间片,实际只有几十毫秒 人为感觉好像是多线程。
3:对于多线程来说,存在等待cpu调度的时候,该线程状态是为就绪状态,如果被cpu调度,则该线程状态为运行状态。当cpu切换其他线程时,它则又会变成就绪状态。
3 创建线程的方式 (推荐我的另一篇 实际使用jdk1.8 方式)
3.1 无返回值
继承Thread
public class ThreadDemo 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 ThreadDemo().start();
/* main
Thread-0我是子线程 */
}
}
实现Runnable接口
public class ThreadRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"我是子线程");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
new Thread(new ThreadRunnable()).start();
/* main
Thread-0我是子线程 */
}
}
匿名内部类/jdk8方式
public static void main(String[] args) {
/**
* 匿名内部类方式
*/
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"我是匿名内部类子线程");
//Thread-0我是匿名内部类子线程
}
}).start();
/** jdk8 形式
*
*/
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"我是jdk8子线程");
//Thread-1我是jdk8子线程
}).start();
/**
* 指定线程名称
*/
new Thread(()->
System.out.println(Thread.currentThread().getName()+"我是指定线程名子线程"),"订单线程"
//订单线程我是指定线程名子线程
).start();
}
3.2 有返回值
Callable 方式一(匿名内部类方式+线程池) 推荐
@Autowired com.example.juc.mapper.TechnicalReviewMapper TechnicalReviewMapper;
@RequestMapping("/test")
public TechnicalReview test() throws ExecutionException, InterruptedException {
//创建线程池
ExecutorService pool = new ThreadPoolExecutor(2, 20, 2000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
//创建任务
FutureTask<TechnicalReview> futureTask = new FutureTask<TechnicalReview>(new Callable<TechnicalReview>() {
@Override
public TechnicalReview call() {
TechnicalReview technicalReview = TechnicalReviewMapper.selectByPrimaryKey(1L);
return technicalReview;
}
});
//把任务给线程池
pool.submit(futureTask);
//获取执行结果
TechnicalReview event = futureTask.get();
//优雅关闭 (实际不会这么用线程池)
pool.shutdown();
return event;
}
Callable 方式二(不推荐,要用非常老的方式 调用sql, 不能使用spring管理的类)
@Component
public class ThreadCallable implements Callable<TechnicalReview> {
@Autowired
com.example.juc.mapper.ReviewMapper TechnicalReviewMapper;
@Override
public TechnicalReview call() throws Exception {
System.out.println("call=="+Thread.currentThread().getName());
//报空指针
TechnicalReview technicalReview = TechnicalReviewMapper.selectByPrimaryKey(1L);
return technicalReview;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadCallable threadCallable = new ThreadCallable();
FutureTask<TechnicalReview> technicalReviewFutureTask = new FutureTask<>(threadCallable);
new Thread(technicalReviewFutureTask).start();
TechnicalReview technicalReview = technicalReviewFutureTask.get();
System.out.println(technicalReview);
}
}