The All-in-One Note (13)

源码:

public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(); }

核心线程数和最大线程数一样,稳定高负荷工作,因此没用超出核心线程数回收的情况keepAliveTime 设置为0,等待队列用LinkedBlockingQueue无界队列

newSingleThreadExecutor 用于串行执行任务的场景,每个任务必须按顺序执行,不需要并发执行

源码:

public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }

解释:

类似于newFixedThreadPool,只是顾名思义池中只有一个线程干活,相当于串行

newCachedThreadPool 用于并发执行大量短期的小任务,或者是负载较轻的服务器

源码:

public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }

解释:

没用核心线程,最大线程数无限,线程60秒没任务干就停止 ,等待队列用直接握手队列SynchronousQueue,任务直接交给线程执行不会保存

newScheduledThreadPool 用于需要多个后台线程执行周期任务,同时需要限制线程数量的场景

源码:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); } private static final long DEFAULT_KEEPALIVE_MILLIS = 10L;

解释:

ScheduledThreadPoolExecutor继承自ThreadPoolExecutor,使用优先级队列DelayedWorkQueue,运行时间短的任务先执行,否则先等待的先执行

newSingleThreadScheduledExecutor 用于需要后台单线程执行周期任务

解释:

单线程执行版的newScheduledThreadPool ,保证任务串行执行,保证串行返回

The All-in-One Note

synchronized关键字

作用:

同步

可见性

使用方式

获取对象锁

同步代码块: 指定加锁对象,对给定对象加锁

synchronized(this){}

同步非静态方法: 作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁

public synchronized void methodA(){}

获取类锁

同步代码块: 指定加锁的类,对给定类加锁

synchronized(类名.class){}

同步静态方法: 作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁

public synchronized static void methodA(){}

实现方式

同步代码块:使用了monitorenter和monitorexit指令

同步方法:通过方法修饰符上的ACC_AYNCHRONIZED实现

monitorexit结束时会把更新直接刷入主内存

JVM中锁升级流程

The All-in-One Note

volatile关键字

作用:

保证数据线程可见性

避免指令重排

实现:

在字节码中加入了 lock 指令:

锁总线,其它CPU对内存的读写请求都会被阻塞,直到锁释放,不过实际后来的处理器都采用锁缓存替代锁总线,因为锁总线的开销比较大,锁总线期间其他CPU没法访问内存,通过缓存一致性协议确保拿到缓存值是最新的

lock后的写操作会把已修改的数据写回内存,同时让其它线程相关缓存行失效,从而重新从主存中加载最新的数据

不是内存屏障却能完成类似内存屏障的功能,阻止屏障两边的指令重排序

如何终止线程

stop方法(别用)

立刻终止线程,过于粗鲁

清理工作可能完成不了

会立即释放锁,有可能引起线程不同步

interrupt方法

阻塞状态下会推出阻塞状态,抛出InterruptedException;运行状态下设置中断标志位为true,继续运行,线程自行检查标志位主动终止,相对温柔

线程如何通信

线程的通信是指线程之间以何种机制来交换信息,在编程中,线程之间的通信机制有两种,共享内存和消息传递

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyysp.html