继承Thread类
public class Main {
public static void main(String[] args) {
Thread t = new MyThread();
t.start(); // 启动新线程
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("start new thread!");
}
}
实现Runnable接口 (方法没有返回值)
public class Main {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start(); // 启动新线程
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("start new thread!");
}
}
实现Callable接口 Callable接口是一个泛型接口,可以返回指定类型的结果。对线程池提交一个Callable任务,可以获得一个Future对象,可以用Future在将来某个时刻获取结果
public class Main {
public static void main(String[] args) {
Thread t = new Thread(new MyCallable());
t.start(); // 启动新线程
}
}
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "start new thread!";
}
}
手动创建线程池
-
4种常见线程池
-
CachedThreadPool:可缓存的线程池,该线程池中没有核心线程,非核心线程的数量为Integer.max_value,就是无限大,当有需要时创建线程来执行任务,没有需要时回收线程,适用于耗时少,任务量大的情况。
-
SecudleThreadPool:周期性执行任务的线程池,按照某种特定的计划执行线程中的任务,有核心线程,但也有非核心线程,非核心线程的大小也为无限大。适用于执行周期性的任务。
-
SingleThreadPool:只有一条线程来执行任务,适用于有顺序的任务的应用场景。
-
FixedThreadPool:定长的线程池,有核心线程,核心线程的即为最大的线程数量,没有非核心线程
-
-
创建线程池
/** 一、创建线程池的7个参数 1、corePoolSize 线程池的核心线程数,无存活时间 2、maximumPoolSize 能容纳的最大线程数 3、keepAliveTime 除核心线程外 空闲线程空闲时存活的最大时间 4、unit 存活时间的单位 5、workQueue 存放提交但未执行任务的队列,执行的是FIFIO原则(先进先出) 6、threadFactory 创建线程的工厂类 7、handler 等待队列满后的拒绝策略 第一种AbortPolicy:不执行新任务,直接抛出异常,提示线程池已满 第二种DisCardPolicy:不执行新任务,也不抛出异常 第三种DisCardOldestPolicy:将消息队列中的第一个任务丢弃,并让当前新进来的任务执行 第四种CallerRunsPolicy:使用调用者线程来执行当前任务 */ ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(4, 8, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory); -
使用
ThreadFactoryBuilder创建自定义线程名称的ThreadFactoryThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("窗口-%d").build(); -
创建任务
for (int i = 0; i < 3; i++) { poolExecutor.execute(()->{ for (int a = 0; a <= 40 ; a++) { ticket.saleTicket();}}); } -
关闭线程池
// 将线程池状态置为SHUTDOWN。平滑的关闭ExecutorService,当此方法被调用时,ExecutorService停止接收新的任务并且等待已经提交的任务(包含提交正在执行和提交未执行)执行完成。当所有提交任务执行完毕,线程池即被关闭。 poolExecutor.shutdown(); // 接收人timeout和TimeUnit两个参数,用于设定超时时间及单位。当等待超过设定时间时,会监测ExecutorService是否已经关闭,若关闭则返回true,否则返回false。一般情况下会和shutdown方法组合使用。 poolExecutor.awaitTermination(1000L, TimeUnit.SECONDS);