[1] Thread家族
[1.1] Thread和Runnable:
Thread是Java中的一个类,用于表示一个线程,它实现了Runnable接口。
通过创建Thread对象,可以创建并启动一个新的线程,执行指定的代码。
public class Thread implements Runnable { private volatile String name; ... public Thread(Runnable var1) { this.init((ThreadGroup)null, var1, "Thread-" + nextThreadNum(), 0L); } ... }
Runnable是一个接口,它定义了一个run()方法。通过实现Runnable接口并实现其中的run()方法,可以创建一个可执行的任务,然后可以通过将其传递给Thread类的构造函数来创建一个线程。
Runnable接口可以让一个类变成一个可执行的任务,从而实现多线程编程。
public interface Runnable { void run(); }
通常情况下,使用Runnable接口来创建线程比继承Thread类更为灵活,因为Java不支持多继承,如果一个类已经继承了其他类,就无法再继承Thread类了。
此外,使用Runnable接口可以使得代码更为清晰,因为线程的执行逻辑被定义在run()方法中,而不是在Thread类的子类中。
[1.2] ThreadFactory:
ThreadFactory是Java中的一个接口,用于创建新线程。
public interface ThreadFactory { Thread newThread(Runnable var1); }
ThreadFactory接口定义了一个名为newThread的方法,需要Runnable对象作为其参数,并返回一个新的Thread对象。ThreadFactory提供了一种定制线程创建的方法,比如设置它们的名称、优先级、守护进程状态和线程组。
下面是一个如何使用ThreadFactory创建新线程:
ThreadFactory threadFactory = new ThreadFactory() { public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName("MyThread"); t.setPriority(Thread.MAX_PRIORITY); t.setDaemon(true); return t; } }; ExecutorService executor = Executors.newFixedThreadPool(10, threadFactory); executor.execute(new Runnable() { public void run() { // Code to be executed in the new thread } });
[1.3] Thread生命周期:
Thread的生命周期可以分为以下几个阶段:
· 新建状态(New):当创建一个Thread对象时,线程处于新建状态。此时线程尚未开始执行,也不具有执行上下文。
· 就绪状态(Runnable):当调用start()方法启动线程时,线程进入就绪状态。此时线程具有执行上下文,但还没有分配到CPU时间片。
· 运行状态(Running):当线程获得CPU时间片并开始执行时,线程进入运行状态。此时线程正在执行任务。
· 阻塞状态(Blocked):当线程因为某些原因无法继续执行时,线程进入阻塞状态。例如,线程等待IO操作完成、等待获取锁、等待其他线程执行完毕等情况都会导致线程进入阻塞状态。
· 死亡状态(Dead):当线程执行完毕或者因为异常终止时,线程进入死亡状态。此时线程不再具有执行上下文。
[2] 线程池
[2.1] 创建线程池的2种方式:
【1】通过Executor框架的工具类Executors来创建。可以创建多种类型的 ThreadPoolExecutor:
· FixedThreadPool:该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。
· SingleThreadExecutor:该方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。
· CachedThreadPool:该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。
· ScheduledThreadPool:该返回一个用来在给定的延迟后运行任务或者定期执行任务的线程池。
【2】通过ThreadPoolExecutor构造函数手动定义创建。
public ThreadPoolExecutor( int corePoolSize,//线程池的核心线程数量 int maximumPoolSize,//线程池的最大线程数 long keepAliveTime,//当线程数大于核心线程数时,多余的空闲线程存活的最长时间 TimeUnit unit,//时间单位 BlockingQueue<Runnable> workQueue,//任务队列,用来储存等待执行任务的队列 ThreadFactory threadFactory,//线程工厂,用来创建线程,一般默认即可 RejectedExecutionHandler handler//拒绝策略,当提交的任务过多而不能及时处理时,我们可以定制策略来处理任务 )