Thread、Runnable、线程池

简介: Thread是Java中的一个类,用于表示一个线程,它实现了Runnable接口。通过创建Thread对象,可以创建并启动一个新的线程,执行指定的代码。

[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//拒绝策略,当提交的任务过多而不能及时处理时,我们可以定制策略来处理任务
)



相关文章
|
3天前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
3天前
|
安全 Java API
【JavaEE】多线程编程引入——认识Thread类
Thread类,Thread中的run方法,在编程中怎么调度多线程
|
1月前
|
Java C# Python
线程等待(Thread Sleep)
线程等待是多线程编程中的一种同步机制,通过暂停当前线程的执行,让出CPU时间给其他线程。常用于需要程序暂停或等待其他线程完成操作的场景。不同语言中实现方式各异,如Java的`Thread.sleep(1000)`、C#的`Thread.Sleep(1000)`和Python的`time.sleep(1)`。使用时需注意避免死锁,并考虑其对程序响应性的影响。
|
1月前
|
安全 Java
在 Java 中使用实现 Runnable 接口的方式创建线程
【10月更文挑战第22天】通过以上内容的介绍,相信你已经对在 Java 中如何使用实现 Runnable 接口的方式创建线程有了更深入的了解。在实际应用中,需要根据具体的需求和场景,合理选择线程创建方式,并注意线程安全、同步、通信等相关问题,以确保程序的正确性和稳定性。
123 11
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
35 3
|
2月前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
57 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
41 2
|
2月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
47 1
|
1月前
|
Java
为什么一般采用实现Runnable接口创建线程?
因为使用实现Runnable接口的同时我们也能够继承其他类,并且可以拥有多个实现类,那么我们在拥有了Runable方法的同时也可以使用父类的方法;而在Java中,一个类只能继承一个父类,那么在继承了Thread类后我们就不能再继承其他类了。
28 0
|
6天前
|
NoSQL Redis
单线程传奇Redis,为何引入多线程?
Redis 4.0 引入多线程支持,主要用于后台对象删除、处理阻塞命令和网络 I/O 等操作,以提高并发性和性能。尽管如此,Redis 仍保留单线程执行模型处理客户端请求,确保高效性和简单性。多线程仅用于优化后台任务,如异步删除过期对象和分担读写操作,从而提升整体性能。
21 1