目录
2,synchronized关键字和 volatile关键字的区别
5,执行 execute方法和 submit方法的区别是什么呢?
1,synchronized关键字
解决的是多个线程间访问资源的同步性。被其修饰的方法或者代码块在任意时刻只能有一个线程执行。
-
修饰实例方法:作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁。
-
修饰静态方法:也就是给当前类加锁,会作用于类的所有对象实例,因为静态成员不属于任何一个实例对象,是类成员( static表明这是该类的一个静态资源,不管new了多少个对象,只有一份)。所以如果一个线程A调用一个实例对象的非静态synchronized方法,而线程B需要调用这个实例对象所属类的静态 synchronized方法,是允许的,不会发生互斥现象,因为访问静态 synchronized方法占用的锁是当前类的锁,而访问非静态 synchronized方法占用的锁是当前实例对象锁。
-
修饰代码块:指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
总结: synchronized关键字加到 static静态方法和 synchronized( class)代码块上都是是给Cass类上锁。 synchronized关键字加到实例方法上是给对象实例上锁。尽量不要使用 synchronized( string a)因为VM中,字符串常量池具有缓存功能。
2,synchronized关键字和 volatile关键字的区别
volatile关键字是线程同步的轻量级实现,性能稍微好些。但 volatile只修饰变量。
synchronized关键字后来引入的偏向锁和轻量级锁等优化方式提升了效率,实际开发场景还是较多。
volatile多线程访问 不会发生阻塞,而 synchronized关键字可能会发生阻塞。
volatile保证数据可见性,但不保证原子性。synchronized关键字两者都能保证。
volatile主要用于解决变量在多个线程之间的可见性,而 synchronized解决的是多个线程之间访问资源的同步性。
3,为啥用线程池?
●降损耗。对已创建的线程重复使用,降低线程创建和销毁消耗。
●提速度。任务到达的时候,可以不需要等到线程创建就能立即执行。
●提高线程可管理性。线程是稀缺资源,使用线程池可以进行统一的分配,调优和监控。
4,Runnable接⼝和Callable接⼝?
Runnable较早,不会返回结果或抛出检查异常,后来的 Callable接口可以。工具类 Executors可以实现 Runnable对象和 Callable对象之间的相互转换。
@FunctionalInterface
public interface Runnable{
public abstract void run();
}
@FunctionalInterface
public interface Callable<V>{
V call() throws Exception;
}
5,执行 execute方法和 submit方法的区别是什么呢?
1. execute() 提交不需要返回值的任务,故无法判断任务是否被线程池执行成功与否。
2. submit() 提交需要返回值的任务。线程池会返回一个 Future类型的对象来判断任务是否执行成功。
并且可以通过Future的get() 方法来获取返回值,但是会阻塞当前线程直到任务完成,而使用get( long timeout, Timeunit unit)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。
6,线程池的创建?
“阿里” 规范不让用 Executors去创建,而通过ThreadPoolexecutor。因为前者会产生堆积请求和大量线程导致OOM内存耗尽。
https://blog.csdn.net/hollis_chuang/article/details/83743723 大佬解析
FixedThreadPool(固定线程数的线程池)
ChachedThreadPool(缓存型线程池)
SingleThreadExecutor(单线程线程池)
ScheduledThreadPool(周期性调度线程池)