JAVA创建线程的方法
1、继承Thread类创建线程
public class ThreaDemo extends Thread{
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + " run")
}
}
2、实现Runnable接口创建线程
public class RunnableDemo implements Runnable{
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + " run")
}
public static void main(String[] args){
RunnableDemo runnableDemo = new RunnableDemo();
Thread thread = new Thread(RunnableDemo);
thread.start();
System.out.println(Thread.currentThread().getName() + " run")
}
}
3、使用Callable和Future创建线程
public class CallableDemo implements Callable<Integer>{
@Override
public Integer call(){
System.out.println(Thread.currentThread().getName() + " call")
return 0
}
}
public calss CallableTest{
public static void main(String[] args){
FutureTask<Integer> futureTask = new FutureTask(new CallableDemo());
Thread thread = new Thread(futureTask);
thread.start();
System.out.println("返回结果 " + futureTask.get());
System.out.println(Thread.currentThread().getName() + " main")
}
}
运行结果
Thread-0 call
返回结果 0
main main
4、使用线程池创建线程
使用Executor框架,提供四种线程池
1、newCachedThreadPool
- newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则创建线程。
2、newFixedThreadPool
- newFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3、newScheduledThreadPool
- newScheduledThreadPool创建一个周期性线程池,支持定时及周期性任务执行。
4、newSingleThreadExecutor
- newSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。
举例:newFixedThreadPool
public class ThreadDemo extend Thread{
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + " 正在执行")
}
}
public class TestFixedThreadPool{
public static void main(String[] args){
// 创建一个可重用固定线程数的线程池
ExecutorService pool = Executor.newFixedThreadPool(3);
// 创建实现了Runnable接口的实例
Thread t1 = new ThreadDemo();
Thread t2 = new ThreadDemo();
Thread t3 = new ThreadDemo();
// 将线程放入线程池中
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
//关闭线程池
pool.shutdown();
}
}
5、线程池的七大参数
- corePoolSize:核心线程数,定义了最小可以同时运行的线程数量。
- maximumPoolSize:线程中允许存在的最大工作线程数量。
- workQueue:存放任务的阻塞队列。新来的任务会先判断当前运行的线程数是否达到核心线程数,如果达到的话,任务就会先放到阻塞队列。
- keepAliveTime:当线程池中的数量大于核心线程数时,如果没有新的任务提交,核心线程外的线程不会立刻销毁,而是会等到时间超过keepAliveTime时才会被销毁。
- unit:keepAliveTime参数的时间单位。
- threadFactory:为线程池提供提供创建新线程的线程工程。
- handler:线程池任务队列超过maxinumPoolSize之后的拒绝策略。
线程池的执行流程:
6、线程池已满时的拒绝策略
当同时运行的线程数量达到最大线程数并且阻塞队列也已经放满了任务时,ThreadPoolExecutor会指定一些饱和策略。主要有以下四种类型:
- AbortPolicy策略:该策略会直接抛出异常拒绝新任务。
- CallerRunsPolicy策略:当线程池无法处理当前任务时,会将该任务交由提交任务的线程来执行。
- DiscardPolicy策略:直接丢弃新任务。
- DiscardOlddestPolicy策略:丢弃最早的未处理的任务请求。