在生产环境中,使用Executors提供的快捷方法(如newFixedThreadPool、newCachedThreadPool等)创建线程池是不推荐的,主要原因如下: 推荐做法 建议在生产环境中使用ThreadPoolExecutor类手动创建线程池,并根据业务需求进行详细配置。例如: 通过这种方式,可以更精确地控制线程池的行为,确保其在高并发环境下稳定运行,并具备良好的监控和调试能力。
在生产环境中,使用Executors提供的快捷方法(如newFixedThreadPool、newCachedThreadPool等)创建线程池是不推荐的,主要原因如下: 推荐做法 建议在生产环境中使用ThreadPoolExecutor类手动创建线程池,并根据业务需求进行详细配置。例如: 通过这种方式,可以更精确地控制线程池的行为,确保其在高并发环境下稳定运行,并具备良好的监控和调试能力。
什么是内存泄漏? 不再用到的内存,没有及时释放,就叫做内存泄漏。 对于持续运行的服务进程,必须及时释放内存,否则内存占用率越来越高,轻则影响系统性能,重则导致进程崩溃。 ThreadLocal是怎么造成内存泄露的呢? 如果发生了下面的情况: 如果ThreadLocal是null了,也就是要被GC回收了, 但是此时我们的ThreadLocalMap(thread 的内部属性)生命周期和Thread的一样,它不会回收,这时候就出现了一个现象。 总之,就是ThreadLocalMap的key没了,但是value还在,这就…
以下,基于JDK1.8。 1. 线程复用 我们知道Thread.start执行之后,线程就不能再次执行了,那ThreadPoolExecutor是如何做到线程复用的呢? 原理很简单,在实际执行的线程外部套一个Thread,外层Thread的run方法while循环执行实际执行线程的run方法,实现线程的复用并且执行之后不销毁。下面是伪代码: // 任务等待队列 BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue(); new Threa…
背景 只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的。如果只是创建三个线程然后执行,最后的执行顺序是不可预期的。这是因为在创建完线程之后,线程执行的开始时间取决于CPU何时分配时间片,线程可以看成是相对于的主线程的一个异步操作。 public class FIFOThreadExample { public synchronized static void foo(String name) { System.out.print(name); } public static void main(St…
当提起这三个词的时候,是不是很多人都认为分布式=高并发=多线程? 当面试官问到高并发系统可以采用哪些手段来解决,或者被问到分布式系统如何解决一致性的问题,是不是一脸懵逼? 确实,在一开始接触的时候,不少人都会将三者混淆,误以为所谓的分布式高并发的系统就是能同时供海量用户访问,而采用多线程手段不就是可以提供系统的并发能力吗? 实际上,他们三个总是相伴而生,但侧重点又有不同。 什么是分布式? 分布式更多的一个概念,是为了解决单个物理服务器容量和性能瓶颈问题而采用的优化手段。 该领域需要解决的问题极多,在不同的技术层面上…
什么是线程安全? 线程安全是指保证多线程环境下共享的、可修改的状态的正确性。 线程安全需要保证几个基本特性 原子性:相关操作不会中途被其他线程干扰,一般通过同步机制实现。 可见性:一个线程修改了某个共享变量,其状态能够立即被其他线程知晓,通常被解释为将线程本地状态反映到主内存上,volatile就是负责保证可见性的。 有序性:保证线程内串行语义,避免指令重排。 大部分情况下,为了保证线程安全,就要用到锁,加上锁后,每次只允许一个线程运行这段代码,也就是每个时间只能有一个线程访问共享数据。这样就实现了线程安全。 JA…
volatile作用 volatile主要是为了解决多线程内存不可见问题。 对于一写多读,是可以解决变量同步问题,但是如果多写,同样无法解决线程安全问题。 其次是为了保证代码的有序性。 虚拟机在编译的时候,是有可能把代码的顺序进行重排序的,不一定会按照我们写的代码的顺序来执行,对于有些代码进行重排序之后,虽然对变量的值没有造成影响,但有可能会出现线程安全问题的。 如果一个变量被声明volatile的话,那么这个变量不会被进行重排序,也就是说,虚拟机会保证这个变量之前的代码一定会比它先执行,而之后的代码一定会比它慢执…
序 为什么要用线程池?什么情况下才会用到线程池? 并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。 因此,就用到了线程池;线程池中的线程可以复用,就是执行完一个任务,并不被销毁,而是继续执行下一个任务。 如下使用线程: public class Test{ public static void main(String[] args) { long start = System.currentTimeMil…
一身转战三千里,一剑曾挡百万师。
COPYRIGHT © 2025 lifengdi.com. ALL RIGHTS RESERVED.
Theme Kratos Made By Seaton Jiang