多线程、线程池总结

176 阅读5分钟

线程: 进程中负责执行的执行单元。一个进程中至少有一个线程

多线程:解决多任务同步时执行的需求,合理使用cpu资源。多线程运行是根据CPU切换 完成的,如何切换线程由CPU决定,因此多线程运行具有不确定性。

创建线程的两种方法: 一、继承Thread类,扩展线程。 创建线程对象并用start()方法启动线程

二、实现Runnable接口 面试题: ① 用Runnable还是Thread? java中类不支持多重继承,但允许调用多个接口。如果还要继承其他类,调用Runnable接口

②Runnable 和Callable 有什么不同? Runnable在JDK1.0就有,Callable在JDK1.5增加。主要区别是Callable的call()方法 可以返回值和抛出异常,但Runnable的run()方法没有这些功能。

Runnable和Callable源码:

public interface Runnable { public void run(); }

public interface Callable { V call() throws Exception; }

三、wait()、notify()、notifyAll()

wait(): 导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒 ,该方法只能在同步方法中调用。

notiy():随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态,该方法 只能在同步方法或同步代码块内部调用。

notifyAll():解除所有那些在该对象上调用wait方法的线程的阻塞状态,只能在 同步方法或同步代码块内部调用。

volatile 关键字: volatile 是一个特殊修饰符,只有成员变量才能使用。volatile变量可以保证下 一个读取操作会在前一个写操作之后发生。

ThreadLocal变量: ThreadLocal是Java里一种特殊的变量。每个线程都有一个ThreadLocal就是每个线程都拥有 了自己独立的一个变量,竞争条件被彻底消除了。

join()方法: 作用是让调用该方法的Thread完成run()方法后,在执行join()后面的方法。

yiled()方法: 线程放弃运行,将cpu的控制权让出,但可能马上被调度机制选中运行,依赖于 线程优先级。

线程调度策略:

一、抢占式调度策略: Java运行时系统线程调度算法是抢占式的,线程优先级比其他处于就绪态, 运行时系统选择该线程。如果是同级的,线程调度程序选择非抢占式的轮转的调度顺序。

二、时间片轮转调度策略: 从就绪状态的线程中选择优先级最高的线程分配一定cpu时间运行,时间结束后再选择其他 线程运行。当线程结束、yield或进入阻塞状态,优先级低的线程才会执行。优先级相同 的两个线程都在等待CPU,则调度程序以轮转的方式选择运行线程。

线程池:

阻塞队列: 有界|无界 ①队列满,只能进行出队操作,所有入队操作必须等待,被阻塞。 ②队列空,只能进行入队操作,所有出队操作必须等待,被阻塞。

优点: ①避免线程的创建和销毁带来的性能开销。 ②避免大量的线程间因互相抢夺系统资源导致的阻塞现象。 ③能够对线程进行简单的管理并提供定时执行、间隔执行等功能。

顶级接口Executor,真正的线程池接口是ExecutorService,ExecutorService默认实现 是ThreadPoolExecutor;普通类Executors里面调用的就是ThreadPollExecutor.

Executors提供的四种线程池: ①newCachedThreadPool是一个可根据需要创建新线程的线程池,

参数: corePoolSize: 核心线程数量,一般情况下不管有没有任务都会一直在线程池中存货 maximumPoolSize:最大线程数量,活动线程达到这个值,后续新任务才会被阻塞 keepAliveTime: 控制线程闲置时的超时时长,超过则终止该线程。一般用于非核心线程, 只有在ThreadPollExecutor中的方法allowCoreThreadTimeOut(boolean value)设置为true, 才用于核心线程 unit:指定keepAliveTime单位,小时、分钟、秒、毫秒 workQueue:线程池的任务队列,通过线程池execute方法将任务Runnable存储在队列中 threadFactory:线程工厂,用来为线程池创建新线程 handler:线程拒绝策略

拒接策略类型:都是线程队列已满 ①AbortPolicy 丢弃任务并抛异常,默认的拒绝策略 ②DiscardPolicy 丢弃任务,但不抛异常。 ③DiscardOldestPolicy 丢弃队列最前面的任务,然后重新提交被拒接的任务 ④CallerRunsPolicy 由调用线程处理该线程任务

线程池的五大状态: Running: 能接受新任务以及处理已添加的任务 Shutdown: 不接受新任务,可以处理已经添加的任务 调用shutdown(不提交任务,但队列里面有任务,执行完成后) Stop:不接受新任务,不处理已经添加的任务,并且中断正在处理的任务。 在任务队列中依旧存在的,会执行 shutdownNow(发一个中断信号,线程立马安全退出) 任务队列中依旧存在的,不会执行 Tidying:所有的任务已经终止,ctl记录的“任务数量”为0,ctl负责记录线程池的运行状态 与活动线程数量 线程池中工作线程数量为0 Terminated:线程池彻底终止,则线程池转变为terminated状态