JAVA创建线程的方法
- 继承Thread类
public class MyThread extends Thread {
@Override
public void run(){
// do something
}
}
- 实现Runnable接口
public class MyRunnable implements Runnable{
@Override
public void run() {
}
}
或者直接在使用的时候
new Thread(() -> {
log.info("run....");
}).start();
- 使用Callable和Future创建线程
创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值
创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。(FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了Future和Runnable接口。
使用FutureTask对象作为Thread对象的target创建并启动新线程
调用FutureTask对象的get()方法来获得子线程执行结束后的返回值
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
return 1111;
}
}
线程池的使用
JAVA中使用ThreadPoolExecutor来创建线程池,参数如下:
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default thread factory.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* 核心线程数,
* 核心线程数时最小的存活线程数量
* 设置allowCoreThreadTimeout=true(默认false)时,核心线程数为0,所限线程都会超时关闭
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* 最大线程数,超过最大线程数将不会再创建线程,新进来的任务会等待或被拒绝
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* 线程空闲时间
* 线程空闲会等待keepAliveTime之后,超时退出,直到线程数为核心线程数
* 如果allowCoreThreadTimeOut=true,会直到线程数为0
* @param unit the time unit for the {@code keepAliveTime} argument
* keepAliveTime的单位
* TimeUnit是一个枚举类型,其包括:
* NANOSECONDS : 1微毫秒 = 1微秒 / 1000
* MICROSECONDS : 1微秒 = 1毫秒 / 1000
* MILLISECONDS : 1毫秒 = 1秒 /1000
* SECONDS : 秒
* MINUTES : 分
* HOURS : 小时
* DAYS : 天
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* 线程池中的任务队列:维护着等待执行的Runnable对象
* SynchronousQueue:这个队列接收到任务的时候,会直接提交给线程处理,而不保留它,无缓冲的等待队列
* 如果所有线程都在工作怎么办?那就新建一个线程来处理这个任务!所以为了保证不出现<线程数达到了maximumPoolSize而不能新建线程>的错误,
* 使用这个类型队列的时候,maximumPoolSize一般指定成Integer.MAX_VALUE,即无限大
* LinkedBlockingQueue:无界缓存的等待队列,这个队列接收到任务的时候,如果当前线程数小于核心线程数,则新建线程(核心线程)处理任务;
* 如果当前线程数等于核心线程数,则进入队列等待。由于这个队列没有最大值限制,即所有超过核心线程数的任务都将被添加到队列中,
* 这也就导致了maximumPoolSize的设定失效,因为总线程数永远不会超过corePoolSize
* ArrayBlockingQueue:有界缓存的等待队列,可以限定队列的长度,接收到任务的时候,如果没有达到corePoolSize的值,则新建线程(核心线程)执行任务,
* 如果达到了,则入队等候,如果队列已满,则新建线程(非核心线程)执行任务,又如果总线程数到了maximumPoolSize,并且队列也满了,则发生错误
* DelayQueue:无界缓存的等待队列,队列内元素必须实现Delayed接口,这就意味着你传进去的任务必须先实现Delayed接口。
* 这个队列接收到任务时,首先先入队,只有达到了指定的延时时间,才会执行任务
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* 任务拒绝处理器,默认是AbortPolicy
* ThreadPoolExecutor类有几个内部实现类来处理这类情况:
* AbortPolicy 丢弃任务,抛运行时异常
* CallerRunsPolicy 执行任务
* DiscardPolicy 忽视,什么都不会发生
* DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code handler} is null
*/
public