【面试系列】八股文之线程篇202306

这篇具有很好参考价值的文章主要介绍了【面试系列】八股文之线程篇202306。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

union all和union的区别

union all:包含重复行

union:不包含重复行

线程池的shutdown()与shutdownNow()方法的区别

shutdown(),调用shutdown方法,线程池会拒绝接收新的任务,处理中的任务和阻塞队列中的任务会继续处理。

public class ThreadPoolTest {

    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2,
                1, TimeUnit.SECONDS, new LinkedBlockingQueue<>(2));
        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName() + "before ~~~");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "after ~~~");
        };
        pool.execute(new Thread(runnable));
        pool.execute(new Thread(runnable));
        pool.execute(new Thread(runnable));

        pool.shutdown();
        System.out.println("活跃线程数:" + pool.getActiveCount() + ",队列任务数:" + pool.getQueue().size());
//        pool.execute(new Thread(runnable));
    }
}

shutdownNow(),会给workers中所有的线程发送interrupt信号,将延迟队列的任务移除并返回。

原理分析

执行任务,尝试添加线程。

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

ThreadPoolExecutor#addWorker,当判断当前线程池的状态已经是SHUTDOWN,返回false,执行拒绝策略。

    private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c);
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }
        // ...
    }

ThreadPoolExecutor#shutdown

    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(SHUTDOWN);
            interruptIdleWorkers();
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
    }

ThreadPoolExecutor#advanceRunState,修改状态为SHUTDOWN

    private void advanceRunState(int targetState) {
        for (;;) {
            int c = ctl.get();
            if (runStateAtLeast(c, targetState) ||
                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }

ThreadPoolExecutor#interruptIdleWorkers(),对于空闲线程,执行interrupt方法。

private void interruptIdleWorkers() {
    interruptIdleWorkers(false);
}

    private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers) {
                Thread t = w.thread;
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }

ThreadPoolExecutor#shutdownNow,修改任务状态为STOP

    public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(STOP);
            interruptWorkers();
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }

ThreadPoolExecutor#interruptWorkers,发送中断信号。

    private void interruptWorkers() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers)
                w.interruptIfStarted();
        } finally {
            mainLock.unlock();
        }
    }

ThreadPoolExecutor#drainQueue,将延迟队列中的任务数据移动到任务list中。

    private List<Runnable> drainQueue() {
        BlockingQueue<Runnable> q = workQueue;
        ArrayList<Runnable> taskList = new ArrayList<Runnable>();
        q.drainTo(taskList);
        if (!q.isEmpty()) {
            for (Runnable r : q.toArray(new Runnable[0])) {
                if (q.remove(r))
                    taskList.add(r);
            }
        }
        return taskList;
    }

spring中 initMethod,@PostConstruct,InitializingBean 初始化的顺序

https://juejin.cn/post/7006965516891848741

@PostConstruct > InitializingBean > initMethod

PostConstruct是实例初始化的时候调用的。

  • 实例初始化会调用aware方法,BeanNameAwareBeanClassLoaderAwareBeanFactoryAware

  • 调用BeanPostProcessor的前置方法

  • 执行InitializingBeanafterPropertiesSet方法。如果有init方法,执行init方法。

  • 调用BeanPostProcessor的后置方法

@PostConstruct 的具体执行的后置处理器是InitDestroyAnnotationBeanPostProcessor

InitializingBean 的执行处理在后置处理器的前置方法执行完后。

initMethod初始化方法在InitializingBean后执行的

Spring 配置中的 classpath: 与 classpath*: 的区别

classpath:,加载一个指定location的资源文件。

classpath*:,会加载所有指定location的资源文件。

守护线程是什么?守护线程和非守护线程的区别是?守护线程的作用是?

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (true) {
                System.out.println(System.currentTimeMillis());
            }
        });
//        t1.setDaemon(true);
        t1.start();
        Thread.sleep(2000);
    }

用户线程就是非守护线程,默认创建的线程就是用户线程。当主线线程停止,用户线程也会停下来。如果是用户线程,则会一直运行。

Java里一个线程调用了Thread.interrupt()到底意味着什么?

  • 如果当前线程处在阻塞状态(例如sleep,join,wait),会退出阻塞状态,抛出InterruptedException异常。
  • 如果正常活动,修改中断标志位为true
public class InterruptTest {

    public static void main(String[] args) throws InterruptedException {
//        t1();
        t2();

    }

    private static void t2() throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread.start();
        TimeUnit.MILLISECONDS.sleep(10);

        thread.interrupt();
    }

    private static void t1() throws InterruptedException {
        Thread thread = new Thread(() -> {
            System.out.println("开始搬砖!");
            //只要代码里没有异常,那么我们可以通过判断线程是否中断来执行业务操作
            //当其他线程发出线程中断信号后就会跳出正在执行的任务,往下执行使线程结束运行。
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("西西弗斯的陷阱:无脑循环,日复一日搬砖!");
            }
            System.out.println("神迹出现,结束搬砖!");
            System.out.println(Thread.currentThread().isInterrupted());//true
            System.out.println(Thread.currentThread().isInterrupted());//true
            System.out.println(Thread.interrupted());//true
            System.out.println(Thread.interrupted());//true
        });
        thread.start();
        TimeUnit.MILLISECONDS.sleep(10);
        System.out.println("启动超级进化形态!");
        thread.interrupt();
    }
}

Thread的静态函数interrupted与Thread的对象函数isInterrupted比较

  • 静态方法Thread.interrupted()会在检测线程中断状态标志是否为true后,还会将中断状态标志重置为false

  • 对象方法thread.isInterrupted()只是检测线程中断状态标志

sleep和wait有什么区别?

  • wait方法必须在synchronized方法块中,sleep可以单独使用。
  • wait方法是Object中的,sleep方法是Thread中的。
  • 唤醒方式不同。sleep自动唤醒,wait是需要别的线程notify唤醒的。
  • sleep在休眠时不释放锁,wait在休眠时会释放锁。
  • 调用sleep方法会进入到TIMED_WAITING,而调用wait方法会进入到WAITING

线程的五种状态

  • 新建。new Thread()
  • 运行。执行start方法之后
  • 无限等待。Object.wait()
  • 有限等待。Object.wait(timeout)或者Thread.sleep(timeout)
  • 阻塞。阻塞是在等待排他锁,synchronized
  • 结束,terminated

Thread.join()方法

Thread.join()会造成主线程阻塞。当线程执行结束之后,会唤醒主线程。

public class ThreadJoinTest {

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
//           while (true){
            System.out.println("t1 run");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//           }
        });
        Thread t2 = new Thread(() -> {
            System.out.println("t2 run");
        });
        Thread t3 = new Thread(() -> {
            System.out.println("t3 run");
        });
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        t3.start();
    }
}

【面试系列】八股文之线程篇202306,面试,面试,职场和发展文章来源地址https://www.toymoban.com/news/detail-523217.html

到了这里,关于【面试系列】八股文之线程篇202306的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java八股文面试[多线程]——两个线程交替打印1-100之间的数字

    一份代码,两个线程,使用synchronize实现: 重写run()方法,将输出1到100之间整数的代码写到同步方法里。 线程1进入到同步方法,输出一个整数后,阻塞并释放锁。 线程2进入到同步方法,唤醒线程1,输出整数后,阻塞并释放锁。 线程1和线程2重复第3步,直到输出所有的整数

    2024年02月11日
    浏览(45)
  • java八股文面试[多线程]——synchronized锁升级详细流程

    偏向锁是JDK6中的重要引进,因为HotSpot作者经过研究实践发现,在大多数情况下,锁不仅不存在多线程竞争,而且总是由 同一线程多次获得 ,为了让线程获得锁的代价更低,引进了偏向锁。 偏向锁是在 单线程 执行代码块时使用的机制,如果在多线程并发的环境下(即线程

    2024年02月10日
    浏览(33)
  • java八股文面试[多线程]——Synchronized的底层实现原理

    笔试:画出Synchronized 线程状态流转 实现原理图 synchronized解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是 同步 ,也称之为”同步锁“。 synchronized的作用是保证在 同一时刻 , 被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的

    2024年02月10日
    浏览(48)
  • java八股文面试[多线程]——并发三大特性 原子 可见 顺序

        AutomicInteger :  volatile + CAS 总线LOCK  MESI 两个协议 TODO volatile的可见性和禁止重排序是怎么实现的: DCL场景:  new操作会在字节码层面生成两个步骤: 分配内存、调用构造器 然后把引用赋值给singleton 不加volatile则会发生指令重排,可能得到不完整的对象 知识来源: 【并

    2024年02月11日
    浏览(53)
  • 【面试八股文】每日一题:谈谈你对线程的理解

    每日一题-Java核心-谈谈你对线程的理解【面试八股文】   Java线程是Java程序中的执行单元。一个Java程序可以同时运行多个线程,每个线程可以独立执行不同的任务。线程的执行是并发的,即多个线程可以同时执行。   Java中的线程有如下的特点 轻量级:线程的创建和销毁

    2024年02月12日
    浏览(45)
  • java八股文面试[多线程]——为什么要用线程池、线程池参数

     速记7个: 核心、最大 存活2 队列 工厂 拒绝 线程池处理流程: 线程池底层工作原理: 线程复用原理:   知识来源: 【并发与线程】为什么使用线程池,参数解释_哔哩哔哩_bilibili 【并发与线程】线程池处理流程_哔哩哔哩_bilibili 【并发与线程】线程池的底层工作原理_哔哩

    2024年02月11日
    浏览(51)
  • java八股文面试[多线程]——主内存和工作内存的关系

    JAVA内存模型(JMM) 共享变量 :如果一个变量在多个线程的工作内存中 都存在副本 ,那么这个变量就是这几个线程的共享变量。 上面的工作内存其实是java内存模型 抽象出来的概念 ,下面简要介绍一下java内存模型(JMM)。 java内存模型( java memory model ): 描述了java程序中各

    2024年02月10日
    浏览(47)
  • java八股文面试[多线程]——ThreadLocal底层原理和使用场景

    源码分析: ThreadLocal中定义了ThreadLocalMap静态内部类,该内部类中又定义了Entry内部类。 ThreadLocalMap定了 Entry数组。 Set方法: Get方法: Thread中定义了两个ThreaLocalMap成员变量: Spring使用ThreadLocal解决线程安全问题  我们知道在一般情况下,只有 无状态的Bean 才可以在多线程环

    2024年02月10日
    浏览(52)
  • java八股文面试[多线程]——sleep wait join yield

          sleep和wait有什么区别 sleep 方法和 wait 方法都是用来将线程进入 阻塞状态 的,并且 sleep 和 wait 方法都可以响应 interrupt 中断,也就是线程在休眠的过程中,如果收到中断信号,都可以进行响应并中断,且都可以抛出 InterruptedException 异常,那 sleep 和 wait 有什么区别呢?

    2024年02月11日
    浏览(45)
  • Java 八股文面试过程系列之synchronized关键字

    本文通过一场虚拟的面试对话,详细解析了Java中的synchronized关键字。从基本用法到底层实现原理,再到性能优化策略,全面提升您对同步机制的理解。

    2024年02月07日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包