学习并发
创建线程的方式
继承Thread类创建
已经继承的类无法使用
1
2
3
4
5
6
7
8
9
10
11
12public class ExtendThread extends Thread {
}
void test1() {
ExtendThread extendThread = new ExtendThread();
log.info("threadId:{}", extendThread.getId());
log.info("threadName:{}", extendThread.getName());
log.info("threadState:{}", extendThread.getState());
log.info("threadPriority:{}", extendThread.getPriority());
}
实现Runnable接口
可以使用匿名对象来进行实现,减少代码
1
2
3
4
5
6
7
void test4(){
Thread thread = new Thread(()->{
System.out.println("lambda+匿名对象类");
},"threadName");
thread.start();
}
利用Callable和FutureTask创建
- 异步?
通过线程池创建
减少线程创建、销毁时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33private static ExecutorServicepool= Executors.newFixedThreadPool(3);
static class DemoThread implements Runnable{
public void run() {
for (int i = 0; i < 10; i++) {
log.info("execute times of runnable thread:{}",i);
}
}
}
static class ReturnableTask implements Callable<Long>{
public Long call() throws Exception{
long startTime = System.currentTimeMillis();
for (int i = 0; i <10; i++) {
log.info("execute times of Callable Thread:{}",i);
}
long used = System.currentTimeMillis() - startTime;
return used;
}
}
public void test5() throws ExecutionException, InterruptedException {
pool.execute(new DemoThread());
// 无返回值
Future future =pool.submit(new ReturnableTask());
Long result = (Long) future.get();
log.info("异步的结果为:{}",result);
// 有返回值
}
线程池
创建线程池
固定数量线程池
- ExecutorService pool = Executors.newFixedThreadPool(3);
缓存线程池
- ExecutorService pool = Executors.newCachedThreadPool();
定时执行线程池
- ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
线程池标准创建方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class ThreadPoolExecutor{
// 核心线程数,即使线程空闲(Idle),也不会回收;
int corePoolSize;
// 线程数的上限;
int maximumPoolSize;
// 线程最大空闲(Idle)时长
long keepAliveTime;
//单位?
TimeUnit unit;
// 任务的排队队列
BlockingQueue<Runnable> workQueue;
// 新线程的产生方式
ThreadFactory threadFactory;
// 拒绝策略
RejectedExecutionHandler handler;
}
向线程池提交的方式
- execute
- 只能接收Runnable类型的参数
- 没有返回值
- 不利于异常捕获
- submit
- 能接受Runnable 和 Callable
- 有返回值
- 可以通过返回的Future(异步执行实例)对象来进行异常捕获
- execute
线程工厂
1
2
3
4
5
6
7
8
9
public void test9() {
ExecutorService my_pool = Executors.newFixedThreadPool(2, new My_thread_factory());
for (int i = 0; i < 5; i++) {
my_pool.execute(new Task());
}
pool.shutdown();
}线程安全
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49package com.example.jc_demo.ThreadTest;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*@AUTHOR:gao_quansui
*@USER:ASUS
*@DATE:2022/10/13 - 15:43
*@PROJECT_NAME:jc_demo
*/
public class ThreadSecurity {
private static intcount= 0;
class increaseVariable implements Runnable {
public void run() {
plus();
}
}
// synchronized 关键字设置同步方法 为粗粒度 整个方法都保护为一个线程执行
// 相反 synchronized 代码块为细粒度 只保证代码块中的被一个线程执行
public synchronized void plus() {
count++;
}
public void test1() throws InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(30);
for (int i = 0; i < 10000; i++) {
pool.submit(new increaseVariable());
}
Thread.sleep(500);
pool.shutdown();
log.info(String.valueOf(count));
}
}