一、同步问题的发生
对属性i进行i++操作不是同步的。i是类属性(方法内的i不在堆内存)
它的动作分解为:
1,从堆内存读取到当前线程栈内存,保存副本ii。
2,ii+1
3,修改i为ii+1。
试想两个线程同时执行i++,就是如果i=1,那么i可能为1,2,3。
二、java的同步机制
synchronized(同步):同步锁,进入它包裹代码块之前,需要获得当前java对象的锁。对于上述过程,必须一个线程全部执行完3个步骤,另一个线程才能开始。
valotile(不稳定的):当使用被修饰变量时候,每要都从堆内存中读取,不要保存副本。
使用的两个条件:
对变量的写操作不依赖于当前值。
该变量没有包含在具有其他变量的不变式中。
atomic(原子):利用了valotile读堆内存的特性。上述执行第3个步骤前,再次读出堆中值和副本ii对比,看原值是否被改变。
三、线程池
线程池基础接口: ExecutorService
基础接口的默认实现:ThreadPoolExecutor
java自带4中线程池(基于ThreadPoolExecutor):
1,Executors.newSingleThreadExecutor保持单个线程池
实现:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
2,Executors.newFixedThreadPool 保持固定个数线程池
实现:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
3,Executors.newCachedThreadPool 可缓存的线程池,执行0到Integer.MAX_VALUE个线程任务
实现:
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
4,Executors.newScheduledThreadPool 定期任务线程池
实现(ScheduledThreadPoolExecutor):
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue());