线程状态转化图
这个图我觉得应该是市面比较通俗易懂的多线程状态转换图,wait()和sleep()的区别显而易见,wait会释放锁然后等待notify()、notifyAll()才会激活然后等待获得该对象锁之后进入可运行状态,而sleep()则是在指定的时间内一直阻塞着线程,到时间后才会进入可运行状态。大家可以自己写个小程序按照图上面的过程实践尝试一把Thread 有个getState()可以查看当前线程的状态!
线程进入BLOCKED状态(很显然A执行后B一直在阻塞中,等待A执行完成后,B才执行完成)
线程池:
Java通过Executors工厂类来产生连接池,该工厂类中包含如下的几个静态工程方法来创建连接池:
1、public static ExecutorService newFixedThreadPool(int nThreads):创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
2、public static ExecutorService newSingleThreadExecutor():创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
3、public static ExecutorService newCachedThreadPool():创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
4、public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize):创建具有指定线程数的线程池,它可以再指定延迟后执行线程任务,corePoolSize指池中所保存的线程数,即使线程是空闲的也被保存在线程池内。
二、ExecutorService类
可以看到上面的5个方法中,前面3个方法的返回值都是一个ExecutorService对象。该ExecutorService对象就代表着一个尽快执行线程的线程池(只要线程池中有空闲线程立即执行线程任务),程序只要将一个Runnable对象或Callable对象提交给该线程池即可,该线程就会尽快的执行该任务。
ExecutorService有几个重要的方法:
1、isShutdown() 如果此执行程序已关闭,则返回 true。
2、isTerminated() 如果关闭后所有任务都已完成,则返回 true。
3、shutdown() 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
4、 List shutdownNow()
试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
5、 Future submit(Callable task)
提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。
6、Future submit(Runnable task)
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
7、 Future submit(Runnable task, T result)
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
更详细的参考JDK API文档。
submit方法是对 Executor接口execute方法的更好的封装,建议使用submit方法。
1.newFixedThreadPool的使用
因为我创建的是一个大小为2的固定长度线程池,根据输出可以看出只有一开始是一起创建了两个线程因为此时线程已经满了这时已经不在创建线程了而是开始执行了后面是执行完一个线程就在创建一个线程,直到把要创建的5都创建并执行完毕。
2.newSingleThreadExecutor的使用
根据输出可有看到从始至终只有一个线程在执行
3.newCachedThreadPool的使用
可变线程池会动态的根据生成的线程数直接复用或创建线程
4.newScheduledThreadPool 延时线程池
网友评论