03_Java多线程面试题

Java多线程面试题

1. 并行和并发有什么区别?

  • 并行:多个处理器或多核处理器同时处理多个任务。
  • 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行。

2. 线程的6种状态?

  • NEW 初始状态,线程被构建,但是没有调用 start() 方法。

  • RUNNABLE 运行状态,就绪和运行两种状态统称作“运行中”。

  • BLOCKED 阻塞状态(被同步锁或者 IO 锁阻塞)

  • WAITING 等待状态,需要被唤醒。

  • TIMED_WAITING 超时等待状态。时间到自动唤醒。

  • TERMINATED 终止状态,表示当前线程已经执行完毕。

3. stop() 和 resume(),suspend() 方法为何不推荐使用?

stop() 停止,resume() 恢复,suspend() 暂停,这些方法在调用后不会释放资源(比如锁)。

4. sleep() 和 wait() 有什么区别?

  • sleep()

    Thread.sleep() 来自Thread 类的方法,不会释放锁,时间到会自动恢复。

  • wait()

    Object.wait() 来自 Object类的方法,会主动释放锁。使用 notify()notifyAll()直接唤醒。

5. run() 和 start() 区别?

  • start() 方法用于启动线程,只能调用一次。

    HelloThread thread = new HelloThread();
    thread.start();
    
  • run() 方法用于执行线程的运行时代码。可以重复调用。

    HelloThread thread = new HelloThread();
    thread.run();
    thread.run();
    

6. 线程池具有哪些状态?

  • RUNNING 这是最正常的状态,接受新的任务,处理等待队列中的任务。

  • SHUTDOWN 不接受新的任务提交,但是会继续处理等待队列中的任务。

  • STOP 不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的线程。

  • TIDYING 所有的任务都销毁了,workCount 为 0,线程池的状态在转换为 TIDYING 状态时,会执行钩子方法 terminated()

  • TERMINATED terminated() 方法结束后,线程池的状态就会变成这个。

7. shutdown()shutdownNow() 区别?

  • shutdown()

    会将线程池的状态设置为SHUTDOWN ,不接受新的任务提交,但是会继续处理等待队列中的任务。

  • shutdownNow()

    会将线程池的状态设置为STOP ,不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的线程。

8. 创建线程池的几个核心构造参数?

//corePoolSize     核心线程池大小
//maximumPoolSize  最大线程池大小
//keepAliveTime    最大存活时间
//unit             keepAliveTime时间单位 
//workQueue        阻塞队列
//ThreadFactory    线程工厂
//RejectedExecutionHandler  拒绝策略
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(20, 50, 30,
                TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(10),
       Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());

9. ArrayBlockingQueue 和 LinkedBlockingQueue区别,各有什么好处?各在什么情况下使用?

  • 队列大小初始化方式不同
    ArrayBlockingQueue 是有界的,必须指定队列的大小;
    LinkedBlockingQueue 是无界的,可以不指定队列的大小,但是默认是Integer.MAX_VALUE

  • 实现不同

    ArrayBlockingQueue 基于数组结构,LinkedBlockingQueue 基于链表结构。

10. 线程池的四种拒绝策略?

  • AbortPolicy 默认策略,丢弃任务并抛出RejectedExecutionException异常 。
  • DiscardPolicy 丢弃任务,但是不抛出异常。
  • DiscardOldestPolicy 喜新厌旧,丢弃队列最前面的任务,然后重新提交被拒绝的任务。
  • CallerRunsPolicy 由调用者的线程处理该任务。

11. 线程池中的线程是怎么创建的?是一开始就随着线程池的启动创建好的吗?

不是。线程池默认初始化后不启动Worker,等待有请求时才启动。

每当我们调用execute()方法添加一个任务时,线程池会做如下判断:

  1. 如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这 个任务;
  2. 如果正在运行的线程数量大于或等于corePoolSize,那么将这个任务放 入队列;
  3. 如果这时候队列满了,而且正在运行的线程数量小于maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;
  4. 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池默认拒绝策略是会抛出异常 RejectExecutionException
  5. 当一个线程完成任务时,它会从队列中取下一个任务来执行。当一个线程无事可做,超过一定的时间keepAliveTime ,线程池会判断如果当前运行的线程数大于corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到corePoolSize的大小。

12. Java 中默认实现好的线程池又有哪些呢?请比较它们的异同。

  • newCachedThreadPool() 创建一个可缓存的线程池

    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    
  • newFixedThreadPool(10) 创建一个定长线程池

    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
    
  • newScheduledThreadPool(10) 创建一个定长线程池,可以定时或周期性的执行任务

    ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);
    
  • newSingleThreadExecutor() 创建一个使用单个 worker 线程的 Executor

    ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
    

阿里巴巴开发手册中指明了建议使用 ThreadPoolExecutor 方式创建线程池。而不建议使用Executors。

13. 如何在 Java 线程池中提交线程?

线程池最常用的提交任务的方法有两种:

  • execute 无返回值

    cachedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    
                }
    });
    
  • submit 可以有返回值

     Future<Object> submit = cachedThreadPool.submit(new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    return new Object();
                }
    });
    

14. 线程池中 execute() 和 submit()方法有什么区别?

  • execute():只能执行 Runnable 类型的任务。
  • submit():可以执行 Runnable 和 Callable 类型的任务。 Callable 类型的任务可以获取执行的返回值,而 Runnable 执行无返回值。

15. 核心线程是在什么时候创建的?

16. 主线程是如何捕捉到子线程的异常的?

17. 服务器最多可以连接的线程数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值