Thread面试点
1,并行和并发:拿一个四车道的高速公路来比喻,车道上同一时间可以并行四辆车,这个数字4就是并行能力;这个车道每1s可以通过20辆车,这个数字20就是并发量。并发是带有单位时间限制的。
2,手动终止线程:
interrupt():
isInterrupted():线程中断标志位
3,线程的start()只能被调用一次,第二次调用会报错
4,yield():让出CPU的执行权
5,join();线程插队。
6,setDeamon():在线程启动之前将线程设置为守护线程。
7,开启线程方式:
方式一:继承Thread类
方式二:实现Runnable接口,传给Thread.
方式三:实现Callable接口,用FutureTask包装,传给Thread.(FutureTask是Runnable的子类)
TaskFuture的实现代码:
//任务执行
Callable<String> stringCallable=new Callable<String>() {
@Override
public String call() throws Exception {
return "我是callable";
}
};
//FutureTask是Runnable的子类
FutureTask<String> futureTask=new FutureTask<String>(stringCallable);
//开启线程
new Thread(futureTask).start();
//获取线程执行的返回值
System.out.println(futureTask.get());
ThreadLocal
作用:做线程隔离;当某些数据是以线程为作用域并且不同线程具有不同的数据副本的时候,就可以考虑采用ThreadLocal
使用方式:
static final ThreadLocal<T> sThreadLocal = new ThreadLocal<T>();
sThreadLocal.set()
sThreadLocal.get()
JDK提供的线程池ThreadPoolExecutor
构造函数:
public ThreadPoolExecutor(int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, //非核心 线程最大空闲时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 任务等待队列
ThreadFactory threadFactory, // 线程创建工厂
RejectedExecutionHandler handler ) { //拒绝策略
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
线程池的工作原理:线程池可以减少创建和销毁线程的次数,从而减少系统资源的消耗,当一个任务提交到线程池时
a. 首先判断核心线程池中的线程是否已经满了,如果没满,则创建一个核心线程执行任务,否则进入下一步
b. 判断工作队列是否已满,没有满则加入工作队列,否则执行下一步
c. 判断线程数是否达到了最大值,如果不是,则创建非核心线程执行任务,否则执行饱和策略,默认抛出异常