Java 核心知识 多线程 线程池
一 Java多线程Java核心知识体系7线程不安全分析Java核心知识体系8Java如何保证线程安全性Java核心知识体系9-并发与多线程线程基础Java核心知识体系10-线程管理Java中的多线程https://www.cnblogs.com/wxd0108/p/5479442.html面试题面试题多线程下单例模式下全局变量共享问题 当多个线程同时访问同一个方法的时候jvm会给每个线程分配单独的局域变量这样就不会出现问题了。面试题多线程调用单例类中的方法会不会造成线程安全问题 答案不会。 局部变量不会受多线程影响但成员变量会受到多线程影响。 多个线程应该是调用的同一个对象的同一个方法 如果方法里无成员变量那么不受任何影响 如果方法里有成员变量只有读操作不受影响存在写操作考虑多线程影响值面试题为什么需要线程池线程池的作用1.统一管理降低资源消耗2.提高响应速度3.提高线程可管理性 面试题线程池队列满了怎么处理线程出异常怎么处理线程的生命周期线程通常都有五种状态创建、就绪、运行、阻塞和死亡Thread 和 Runnable的区别实例化线程对象有所不同extends Thread t.start();implements Runnable new Thread(t).start();实现Runnable接口比继承Thread类所具有的优势1适合多个相同的程序代码的线程去处理同一个资源2可以避免java中的单继承的限制(不能访问父类的私有成员)3增加程序的健壮性代码可以被多个线程共享代码和数据独立4线程池只能放入实现Runable或callable类线程不能直接放入继承Thread的类run()和start()方法的区别run方法是线程的任务处理逻辑的入口方法它由Java虚拟机在运行相应线程时直接调用而不是由应用代码进行调用。调用run方法其实就是当作普通的方法的方式调用。并没有创建一个线程程序中依旧只有一个主线程必须等到run()方法里面的代码执行完毕才会继续执行下面的代码这样就没有达到加入线程的目的。start方法是启动相应的线程。启动一个线程实际是请求Java虚拟机运行相应的线程而这个线程何时能够运行是由线程调度器决定的。start()调用并不表示相应线程已经开始运行这个线程可能稍后运行。创建并启动一个线程真正实现了多线程。无需等待run()方法中的代码执行完毕就可以接着执行下面的代码。此时start()的这个线程处于就绪状态当得到CPU的时间片后就会执行其中的run()方法。这个run()方法包含了要执行的这个线程的内容run()方法运行结束线程终止。start()方法能够异步的调用run()方法但是直接调用run()方法却是同步的无法达到多线程的目的。因此只用通过调用线程类的start()方法才能达到多线程的目的。双重校验锁的单例模式volatile修饰singleton很有必要voliatile防止了指令重排在这里插入代码片volatile关键字在现在的java模型下线程可以把变量保存在本地内存比如寄存器中而不是直接在主内存中进行读写这就可能造成一个线程在主内存中修改了一个变量的值而另外一个线程还继续使用它在寄存器中的变量的拷贝造成数据不一致。sychronized关键字sychronized和volatile的区别实现Runnable和Callable接口的区别https://www.jianshu.com/p/27b7340d8470二 线程池 Executors线程池的作用在实践应用中创建线程池主要是为了减少资源开销减少每次创建、销毁线程的开销提高响应速度请求到来时线程已创建好可直接执行提高响应速度提高线程的可管理性线程是稀缺资源需根据情况加以限制确保系统稳定运行Java中创建线程的4种方式1.继承Thread 2.实现Runnable接口3.实现Callable接口4.线程池Executors 和 ThreadPoolExecutor 自定义线程池。通过 Callable 和 Future 创建线程1.创建 Callable 接口的实现类并实现 call() 方法该 call() 方法将作为线程执行体并且有返回值。2.创建 Callable 实现类的实例使用 FutureTask 类来包装 Callable 对象该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。3.使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。4.调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。Java自带的四种线程池创建方式Executors.newFixedThreadPool(5); //一个饭店5张桌子Executors.newSingleThreadPool(); //一个饭店1张桌子Executors.newCachedThreadPool(); //一个饭店可以动态加桌子newScheduledThreadPool // 定时任务线程池JAVA线程池的四种创建方式和使用场景 https://blog.csdn.net/hekai7217/article/details/147090211关于阿里规约线程资源必须通过线程池提供不允许在应用中自行显式创建线程。线程池不允许Executors去创建而是通过ThreadPoolExecutor的方式这样的处理方式让写的同学更加明确线程池的运行规则规避资源耗尽的风险。说明Executors返回的线程池对象的弊端如下1FixedThreadPool和SingleThreadPool允许的请求队列长度为Integer.MAX_VALUE可能会堆积大量的请求从而导致OOM。2CachedThreadPool允许的创建线程数量为Integer.MAX_VALUE可能会创建大量的线程从而导致OOM。完参考资料Java中的多线程https://www.cnblogs.com/wxd0108/p/5479442.htmlvolatile的设计原理https://mp.weixin.qq.com/s/WTqdSz-lc5zzelJgk4Co8gThreadPoolExecutorhttps://mp.weixin.qq.com/s/ROQMBFw0DWM4sSP-sdy-IA