乐观加锁
- compareAndSet()方法
- ReadWriteLock对向数据结构相对不频繁地写入,但是有多个任务要经常读取这个数据结构的这类情况进行了优化。
- ReadWriteLock使得可以同时有多个读取者,只要他们都不视图写入即可。如果写锁已经被其他任务持有,那么任何读取者都不能访问,直至这个写锁被释放为止。
- -
package com21并发1;
import java.util.EventListener;
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;
/**
* Created by Panda on 2018/5/29.
*/
public class FastSimulation {
static final int N_ELEMENTS=100000;
static final int N_GENS=30;
static final int N_EVOLVERS=50;
static final AtomicInteger[][] GRID=new AtomicInteger[N_ELEMENTS][N_GENS];
static Random random = new Random(47);
static class Evolver implements Runnable{
@Override
public void run() {
while(!Thread.interrupted()){
int element=random.nextInt(N_ELEMENTS);
for (int i = 0; i <N_GENS ; i++) {
int previous=element-1;
if(previous<0) previous=N_ELEMENTS-1;
int next=element+1;
if(next>=N_ELEMENTS) next=0;
int oldValue=GRID[element][i].get();
int newValue=oldValue+GRID[previous][i].get()+GRID[next][i].get();
newValue/=3;
if(!GRID[element][i].compareAndSet(oldValue,newValue)){
System.out.println("old value changed from "+oldValue);
}
}
}
}
}
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i <N_ELEMENTS ; i++) {
for (int j = 0; j <N_GENS ; j++) {
GRID[i][j]=new AtomicInteger(random.nextInt(1000));
}
}
for (int i = 0; i <N_EVOLVERS ; i++) {
executorService.execute(new Evolver());
}
TimeUnit.SECONDS.sleep(5);
executorService.shutdown();
}
}
package com21并发1;
import org.omg.CORBA.TRANSACTION_MODE;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriterList<T> {
private ArrayList<T> lockedList;
private ReentrantReadWriteLock lock=new ReentrantReadWriteLock(true);
public ReadWriterList(int size,T initialValue) {
lockedList=new ArrayList<>(Collections.nCopies(size,initialValue));
}
public T set(int index,T element){
Lock wlock=lock.writeLock();
wlock.lock();
try{
return lockedList.set(index,element);
}finally {
wlock.unlock();
}
}
public T get(int index){
Lock rlock = lock.readLock();
rlock.lock();
try{
if(lock.getReadLockCount()>1){
System.out.println(lock.getReadLockCount());
}
return lockedList.get(index);
}finally {
rlock.unlock();
}
}
public static void main(String[] args) {
new ReadWriterListTest(30,1);
}
}
class ReadWriterListTest{
ExecutorService executorService = Executors.newCachedThreadPool();
private final static int SIZE=100;
private static Random random=new Random(47);
private ReadWriterList<Integer> list = new ReadWriterList<>(SIZE,0);
private class Writer implements Runnable{
@Override
public void run() {
try{
for (int i = 0; i <20 ; i++) {
list.set(i,random.nextInt());
TimeUnit.MILLISECONDS.sleep(100);
}
}catch (InterruptedException e){
}
System.out.println("write finished,shutting down");
executorService.shutdown();
}
}
private class Reader implements Runnable{
@Override
public void run() {
try{
while(!Thread.interrupted()){
for (int i = 0; i < SIZE; i++) {
list.get(i);
TimeUnit.MILLISECONDS.sleep(1);
}
}
}catch (InterruptedException e){
}
}
}
public ReadWriterListTest(int readers,int writers){
for (int i = 0; i < readers; i++) {
executorService.execute(new Reader());
}
for (int i = 0; i <writers ; i++) {
executorService.execute(new Writer());
}
}
}