在现在互联网项目中,经常面对的是高并发的场景,而针对面对高并发的系统架构主要在缓存、分布式数据库、消息队列、分布式部署等进行分享。
如何提高单应用的响应能力就跟线程有莫大的关系了。本文将通过以下内容进行分享:
- 任务
- 线程
- 线程状态
- 线程属性
- 线程池
Part-1:任务
//定义任务:实现Runnable接口
public class LiftOff implements Runnable {
protected int countDown = 10;
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() { }
public LiftOff(int countDown) {this.countDown = countDown; }
public String status() {
return "#" + id + "(" + (countDown > 0 ? countDown : "LiftOff!") + ")";
}
@Override
public void run() {
while (countDown-- > 0) {
System.out.print(status());
Thread.yield();
}
}
}
Part-2:线程调用
Thread thread=new Thread(new LiftOff());
thread.start();
//线程初始化方法
public Thread(
ThreadGroup group, //线程分组,默认是空
Runnable target, //线程执行任务
String name, //线程名称
long stackSize //线程栈大小,默认是0表示忽略
)
Part-3:线程状态
新建、可运行、被阻塞、等待、计时等待、被终止
Part-4:线程属性
- 优先级
//线程优先级:最低1,最高10,默认为5
t.setPriority(int newPriority)
- 守护线程
t.setDaemon(true)
PS:当程序仅剩下守护线程的时候,虚拟机就会退出
Part-5:线程池
构建一个线程有一定代价,因为涉及与操作系统的交互。如果程序中创建大量生命周期很短的线程,应该使用线程池(thread pool)。
- 线程池创建基础类
//Java线程池构建底层方法:
public ThreadPoolExecutor(
int corePoolSize, //线程池工作线程池大小
int maximumPoolSize, //线程池最大工作线程数
long keepAliveTime, //非核心线程空闲等待时长
TimeUnit unit, //非核心线程空闲等待时间单位
BlockingQueue<Runnable> workQueue, //线程池任务等待队列
ThreadFactory threadFactory, //线程构建工厂,默认DefaultThreadFactory
RejectedExecutionHandler handler //
)
- 默认线程池创建方法
//java.util.concurrent.Executors 神明系统不同线程池
//固定线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(
nThreads,
nThreads,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
//单线程实例线程池
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(
new ThreadPoolExecutor(
1,
1,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
//缓存线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(
0,
Integer.MAX_VALUE,
60L,
TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
//计划线程池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
//单个核心计划线程池
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
-
线程池参数比较
拒绝策略
//执行指定任务
public static class CallerRunsPolicy implements RejectedExecutionHandler {
//抛出异常:RejectedExecutionException
public static class AbortPolicy implements RejectedExecutionHandler {
//新任务直接丢弃
public static class DiscardPolicy implements RejectedExecutionHandler {
//将等待队列头部节点丢弃,将新任务放入队尾
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
Part-6:带返回类型任务
- 实现Callable<T>接口
import java.util.Random;
import java.util.concurrent.Callable;
public class RandomDataCallable implements Callable<Integer> {
private final Random random = new Random();
private final Integer randomLimit = 10000;
@Override
public Integer call() throws Exception {
//模拟异步任务
int randomResult = 0;
do {
Thread.currentThread().join(300);
randomResult = random.nextInt(randomLimit);
} while (randomResult % 21 != 0);
return randomResult;
}
}
- 生成Future<T>对象
List<Future<Integer>> futureResults = new ArrayList<>();
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
futureResults.add(executorService.submit(randomDataCallable));
}
- 获取结果
int countTimes = 0;
while (futureResults.stream().filter(Future::isDone).count() != futureResults.size()) {
Thread.currentThread().join(100);
countTimes++;
System.out.print("等待异步任务结果" + countTimes);
}
futureResults.forEach(futureResult->{
try {
System.out.println(futureResult.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
参考资料
- Java核心技术(卷1)基础知识
- Java编程思想