一、创建可变大小的线程池
public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute将重用以前构造的线程(如果线程可用)。 如果现有线程没有可用的,则创建一个新线程并添加到池中。
终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
二、创建延迟连接池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,可安排在给定延迟后运行,或者定期的执行。
三、自定义线程池
ThreadPoolExecutor类提供用户自定义线程池的相关方法。
public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue )
//保留的线程池大小(核心线程池大小,即可直接运行的任务数),线程池的最大值,空闲线程结束的超时时间,表示keepAliveTime的单位,表示存放任务的队列
四、自定义线程池的工作过程:
(1)线程池刚创建时,里面没有一个线程,任务队列是作为参数传进的。
(2)当调用execute()方法添加一个任务时, 线程池会做如下判断:
a) 如果正在运行的线程数量小于corePoolSize ,那么马上创建线程运行这个任务。
b) 如果正在运行的线程数量大于或者等于 corePoolSize,那么将这个任务放入队列。
c) 如果此时队列满了,而且正在运行的线程数 量小于maximumPoolSize,那么还是要创 建线程运行这个任务;
d) 如果队列满了,而且正在运行的线程数量大于或者等于maximumPoolSize,线程池会 于或者等于maximumPoolSize,线程池会抛出异常。
(3)当一个线程完成任务时,它会从队列中取下一个任务来执行。
(4)当一个线程无事可做,超过一定时间( keepAliveTime)时,线程池会判断,如果当前运行的线程数大于corePoolSize,那么这个线程就被停掉。
五、Callable与Runnable不同点
(1)Callable规定的方法是call(),而 Runnable规定的方法是run()。
(2)Callable的任务执行后可返回值,而 Runnable的任务是不能返回值的。
(3)call()方法可抛出异常,而run()方法是不能抛出异常的。
(4)运行Callable任务可得到一个Future对象。
使用Runnable接口实现的线程是没有返回值的,java5之后增加了有返回值的线程实现方式实现Callable接口。
六、线程取得返回值的方法
(1)Future + ExecutorService
(2)FutureTask + ExecutorService
七、实现同步的方法
一种常见办法是使用java内置的监控器。
Java中可用使用关键字synchronized为共享资源加锁。
synchronized可修饰一个代码块或一个方法,使被修饰对象在任一时刻只能有一个线程访问,从而提供了程序的同步执行功能。
八、实现同步-1、同步方法
同步方法:通过在方法声明中加入synchronized关键字来声明synchronized 方法。
public synchronized void methodA() { }
注意:(1)对方法run( )无法加锁,不可避免冲突;
(2)对构造函数不能加锁,否则出现语法错误。
九、实现同步—2、同步块
可以通过synchronized关键字将一个程序块声明为synchronized块。
synchronized(object) {要互斥的语句}