1、Java中的线程是什么?
在Java中,线程是程序执行流的最小单元。每个Java程序都至少有一个主线程,也称为主执行线程,它是程序开始执行时自动创建的。除了主线程外,程序员还可以创建额外的线程来执行并发任务。
2、创建线程的方式有哪些?
Java中的线程由java.lang.Thread类表示,可以通过两种方式创建线程:
继承Thread类:创建一个类并继承Thread类,在该类中重写run()方法,并在其中定义线程执行的任务。然后通过创建该类的对象并调用start()方法来启动线程。
class MyThread extends Thread { public void run() { // 线程执行的任务 } } public class Main { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); // 启动线程 } }
实现Runnable接口:创建一个类实现Runnable接口,在该类中实现run()方法,并在其中定义线程执行的任务。然后通过创建该类的对象,并将其传递给Thread类的构造函数来创建线程,最后调用start()方法启动线程。
class MyRunnable implements Runnable { public void run() { // 线程执行的任务 } } public class Main { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); // 启动线程 } }
3、上述两种方式的优缺点?
继承 Thread 类:
优点:
简单直观:直接继承 Thread 类,重写 run() 方法,代码比较简单,易于理解。
缺点:
类型局限性:Java是单继承的语言,如果已经继承了其他类,则无法再继承 Thread 类,限制了类的扩展性。
不利于共享资源:由于线程类已经继承了 Thread,无法再继承其他类,因此不利于多个线程之间共享资源。
实现 Runnable 接口:
优点:
避免单继承局限性:通过实现 Runnable 接口,可以避免单继承的限制,允许类继续继承其他类。
支持共享资源:由于不是继承线程类,因此可以将多个线程共享的资源放在实现 Runnable 接口的类中,更容易实现资源共享。
缺点:
略微复杂:相比于继承 Thread 类,实现 Runnable 接口稍微复杂一些,需要创建一个实现 Runnable 接口的类,并将其传递给 Thread 类。
一般情况下推荐使用实现 Runnable 接口的方式创建线程,因为它更灵活,可以避免单继承的限制,同时支持共享资源,更符合面向对象设计的原则。
4、什么是Java线程池?
Java线程池是一种用于管理和复用线程的机制,它可以在执行大量异步任务时提供性能的提升。使用线程池可以避免不断创建和销毁线程所带来的性能开销,并能更好地控制资源的使用情况。
5、如何创建Java线程池?
在 Java 中创建线程池通常通过 java.util.concurrent.Executors 类中的静态工厂方法来实现。
创建固定大小的线程池:
// 创建固定大小为 5 的线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
创建单线程的线程池:
ExecutorService executor = Executors.newSingleThreadExecutor();
创建可缓存的线程池:
// 创建可缓存的线程池,线程数会根据需要自动增加或减少
ExecutorService executor = Executors.newCachedThreadPool();
创建定时执行任务的线程池:
// 创建定时执行任务的线程池,参数为核心线程数
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
6、你用到过线程池的哪些参数?
线程池的参数通常取决于你在创建线程池时选择的具体实现和配置。一般来说,线程池的参数可以包括以下几个方面:
a. 核心线程数(Core Pool Size):这是线程池中的基本线程数量,即使它们处于空闲状态也会保持活动状态。当有新任务提交时,线程池会优先使用核心线程来执行任务。
b. 最大线程数(Maximum Pool Size):这是线程池中允许的最大线程数量。如果核心线程已经全部被占用,而且任务队列也已满,那么新任务就会创建额外的线程,直到达到最大线程数为止。超出最大线程数的任务将根据线程池的策略被拒绝执行。
c. 任务队列(Task Queue):任务队列用于存储提交但尚未执行的任务。当所有核心线程都处于忙碌状态时,新任务将被放置在任务队列中等待执行。任务队列的类型可以是有界队列,如`ArrayBlockingQueue`,也可以是无界队列,如`LinkedBlockingQueue`。
d. 线程存活时间(Keep Alive Time):当线程池中的线程数量超过核心线程数时,多余的空闲线程在经过一定时间后会被终止并从线程池中移除,以减少资源消耗。这个时间段即为线程的存活时间。
e. 拒绝策略(Rejected Execution Policy):当任务无法被线程池执行时的处理策略。常见的策略包括抛出异常、丢弃任务、丢弃最旧的任务、或者由调用线程执行任务等。
这些是线程池中常见的参数,你可以根据具体的需求来配置线程池以达到最佳的性能和资源利用率。