PriorityBlockingQueue
其中的任务按照优先级顺序从队列中出来
Semaphore(信号量)
正常的锁(synchronized和Lock)只允许同时有一个任务访问资源
信号量:允许n个任务访问资源
Exchanger
两个任务之间交换对象的栅栏
可以让对象在创建的同时被消费
性能调优
Lock通常比synchronized更高效
synchronized代码简单易读
写代码使用synchronized,调优的时候改成Lock
免锁容器
hashTable和Vector有很多synchronized方法
免锁容器通用策略:读取和写入可以同时发生
在CopyOnWriteArrayList中,写入操作:现有数据复制一个副本,写入操作写给副本,然后一个原子性的替换工作完成全部的写入工作,所以在写入过程中仍然可以读,读的是写入之前的数据
CopyOnWriteSet使用CopyOnWriteArrayList来实现免锁行为
ConcurrentHashMap和ConcurrentLinkedQueue也使用了类似的技术,允许并发写入和读取,在写入完全完成之前读取的仍然是写入之前的数据
乐观锁
只要你使用免锁容器读取就比synchronized的产物快很多,因为省去了加锁和解锁的操作
List
synchronized:无论读取和写入多少次,性能差不多
CopyOnWriteArrayList:如果没有写入,性能很高,即使有写入操作,性能还是比synchronized的产物高
Map
向ConcurrentHashMap添加写入操作对其产生的影响比CopyOnWriteArrayList还小
乐观加锁
使用Atomic能带来性能上的收益
乐观:保持数据为未锁定状态
package com.atomicTest;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Author redarm
* @Date 2020/4/19 8:37 上午
**/
public class FastSimulation {
static final int N_ELEMENTS = 100000;
static final int N_GENES = 30;
static final int N_EVOLVERS = 50;
static final AtomicInteger [] [] GRID = new AtomicInteger[N_ELEMENTS][N_GENES];
static Random random = new Random(1);
static class Evolver implements Runnable{
@Override
public void run() {
while (!Thread.interrupted()){
int element = random.nextInt(N_ELEMENTS);
for(int i=0;i<N_GENES;i++){
int previous = element - 1;
if (previous < 0)
previous = N_ELEMENTS-1;
int next = element + 1;
if (next >= N_ELEMENTS)
next = 0;
int odvalue = GRID[element][i].get();
int newvValue = odvalue + GRID[previous][i].get()+GRID[next][i].get();
newvValue /= 3;
if(!GRID[element][i].compareAndSet(odvalue,newvValue)){
System.out.println("Old value changed from " + odvalue);
}
}
}
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newCachedThreadPool();
for(int i=0;i<N_ELEMENTS;i++){
for(int j=0;j<N_GENES;j++){
GRID[i][j] = new AtomicInteger(random.nextInt(1000));
}
}
for (int i=0;i<N_EVOLVERS;i++){
service.execute(new Evolver());
}
TimeUnit.SECONDS.sleep(5);
service.shutdownNow();
}
}
ReadWriteLock
允许多个任务同时访问数据结构,只要没有写入操作就行
一旦有写入操作,数据结构就会被上锁,同时也无法被读取,直到这个锁被释放为止