提交 e4ba6966 编写于 作者: F feijianjun

Java性能优化权威指南代码1-线程本地,分段map

上级 b84be146
package com.fjj.pa.cas;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 14:58
*/
@Data
@AllArgsConstructor
public class BailoutFuture {
private double interationsPerSecond;
private long recordsAdded, recordsRemoced, nullCounter;
}
package com.fjj.pa.cas;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.*;
import java.util.concurrent.*;
public class BailoutMain {
final public static int TEST_TIME = 120 * 1000;
final public static Random random = new Random(Thread.currentThread().getId());
private static char[] alphabet = {'a', 'b', 'c', 'd', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
private static String[] states = {"Alabama", "Alaska", "Arizona",
"Arkansas", "California", "Colorado", "Connecticut",
"Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
"Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky",
"Louisiana", "Maine", "Maryland", "Massachusetts",
"Michigan", "Minnesota", "Mississippi, Missouri", "Montana", "Nebraska",
"Nevada ", "New Hampshire", "New Jersey, New Mexiew York",
"North Carolina", "North Dakota", "Ohioklahoma0regon", "Pennsylvania",
"Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah Vermont", "Virginia", "Washington",
"West Virgina",
"Wisconsin", "Wyoming"};
public static void main(String[] args) {
final int numberOfThreads = Runtime.getRuntime().availableProcessors();
final int dbSize = TaxPayerBailoutDB.NUMBER_OF_RECORDS_DESIRED;
final int taxPayerListSize = dbSize / numberOfThreads;
System.out.println("Number of threads to run concurrently:" + numberOfThreads);
System.out.println("Tax payer database size:" + dbSize);
//
System.out.println("Createing tax payer database...");
TaxPayerBailoutDB db = new TaxPayerBailoutDbImpl(dbSize);
List<String>[] taxPayerList = new ArrayList[numberOfThreads];
for (int i = 0; i < numberOfThreads; i++) {
taxPayerList[i] = new ArrayList<String>(taxPayerListSize);
}
populateDatabase(db, taxPayerList, dbSize);
System.out.println("\tTax payer database created.");
System.out.println("Allocating(" + numberOfThreads + ")threads...");
ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads);
Callable<BailoutFuture>[] callables = new TaxCallable[numberOfThreads];
for (int i = 0; i < callables.length; i++) {
callables[i] = new TaxCallable(taxPayerList[i], db);
}
System.out.println("\tthreads allocated.");
System.out.println("Starting(" + callables.length + ") threads...");
Set<Future<BailoutFuture>> set = new HashSet<Future<BailoutFuture>>();
for (int i = 0; i < callables.length; i++) {
Callable<BailoutFuture> callable = callables[i];
Future<BailoutFuture> future = pool.submit(callable);
set.add(future);
}
System.out.println("\t(" + callables.length + ")threads started.");
System.out.println("Waiting for " + TEST_TIME / 1000 + "seconds for(" + callables.length + ")threads to complete...");
double iterationsPerSecond = 0;
long recordsAdded = 0, recordsRemoved = 0;
long nullCounter = 0;
int counter = 1;
for (Future<BailoutFuture> future : set) {
BailoutFuture result = null;
try {
result = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("Iterations per second on thread[" + counter++ + "]->" + result.getInterationsPerSecond());
iterationsPerSecond += result.getInterationsPerSecond();
recordsAdded += result.getRecordsAdded();
nullCounter = result.getNullCounter();
}
DecimalFormat df = new DecimalFormat("#.##");
System.out.println("Total iterations per second ---------->" + df.format(iterationsPerSecond));
NumberFormat nf = NumberFormat.getInstance();
System.out.println("Total records added ------------------>" + nf.format(recordsAdded));
System.out.println("Total records removed ---------------->" + nf.format(recordsRemoved));
System.out.println("Total records in db ------------------>" + nf.format(db.size()));
System.out.println("Total null records encountered: ------>" + nf.format(nullCounter));
System.exit(0);
}
private static void populateDatabase(TaxPayerBailoutDB db, List<String>[] taxPayerList, int dbSize) {
for (int i = 0; i < dbSize; i++) {
String key = getRandomTaxPayerId();
TaxPayerRecord tpr = makeTaxPayerRecord();
db.add(key, tpr);
int index = i % taxPayerList.length;
taxPayerList[index].add(key);
}
}
public static String getRandomTaxPayerId() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 20; i++) {
int index = random.nextInt(alphabet.length);
sb.append(alphabet[index]);
}
return sb.toString();
}
public static TaxPayerRecord makeTaxPayerRecord() {
String firstName = getRandomName();
String laseName = getRandomName();
String ssn = getRandomSSN();
String address = getRandomAddress();
String city = getRandomCity();
String state = getRandomState();
return new TaxPayerRecord(firstName, laseName, ssn, address, city, state);
}
private static String getRandomCity() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(5) + 6;
for (int i = 0; i < size; i++) {
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 0) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
private static String getRandomState() {
int index = random.nextInt(states.length);
return states[index];
}
private static String getRandomAddress() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(14) + 10;
for (int i = 0; i < size; i++) {
if (i < 5) {
int x = random.nextInt(8);
sb.append(x + 1);
}
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 5) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
private static String getRandomSSN() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 11; i++) {
sb.append('-');
}
int x = random.nextInt(9);
sb.append(x);
return sb.toString();
}
private static String getRandomName() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(8) + 5;
for (int i = 0; i < 20; i++) {
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 0) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
}
\ No newline at end of file
package com.fjj.pa.cas;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:59
*/
public class TaxCallable implements Callable<BailoutFuture> {
private static long runTimeInMillis = BailoutMain.TEST_TIME;
final private static Random generator = BailoutMain.random;
private long nullCounter, recodesRemoved, newRecordsAdded;
private int index;
private String taxPayerId;
final private List<String> taxPayerList;
final private TaxPayerBailoutDB db;
public TaxCallable(List<String> taxPayerList, TaxPayerBailoutDB db) {
this.taxPayerList = taxPayerList;
this.db = db;
index = 0;
}
@Override
public BailoutFuture call() throws Exception {
long iterations = 0L, elapsedTime = 0L;
long startTime = System.currentTimeMillis();
double iterationsPersecond = 0;
do {
setTaxPayer();
iterations++;
TaxPayerRecord tpr = null;
if (iterations == Long.MAX_VALUE) {
long elapsed = System.currentTimeMillis() - startTime;
iterationsPersecond = iterations / ((double) (elapsed / 1000));
System.err.println("Iteration counter about to overflow ...");
System.err.println("Calculating counter about to second ...");
System.err.println("Iterations per second: " + iterationsPersecond);
iterations = 0L;
startTime = System.currentTimeMillis();
runTimeInMillis -= elapsed;
}
if (iterations % 1001 == 0) {
tpr = addNewTaxPayer(tpr);
} else if (iterations % 60195 == 0) {
tpr = removeTaxPayer(tpr);
} else {
tpr = updateTaxPayer(iterations, tpr);
}
if (iterations % 1000 == 0) {
elapsedTime = System.currentTimeMillis() - startTime;
}
} while (elapsedTime < runTimeInMillis);
if (iterations >= 1000) {
iterationsPersecond = iterations / ((double) (elapsedTime / 1000));
}
BailoutFuture bailoutFuture = new BailoutFuture(iterationsPersecond, newRecordsAdded, recodesRemoved, nullCounter);
return bailoutFuture;
}
private void setTaxPayer() {
if (++index >= taxPayerList.size()) {
index = 0;
}
this.taxPayerId = taxPayerList.get(index);
}
private TaxPayerRecord removeTaxPayer(TaxPayerRecord tpr) {
tpr = db.remove(taxPayerId);
if (tpr != null) {
taxPayerList.remove(index);
recodesRemoved++;
}
return tpr;
}
private TaxPayerRecord addNewTaxPayer(TaxPayerRecord tpr) {
String tmpTaxPayerId = BailoutMain.getRandomTaxPayerId();
tpr = BailoutMain.makeTaxPayerRecord();
TaxPayerRecord old = db.add(tmpTaxPayerId, tpr);
if (old == null) {
taxPayerList.add(tmpTaxPayerId);
newRecordsAdded++;
}
return tpr;
}
private TaxPayerRecord updateTaxPayer(long iteratios, TaxPayerRecord tpr) {
if (iteratios % 1001 == 0) {
tpr = db.get(taxPayerId);
} else {
tpr = db.get(taxPayerId);
if (tpr != null) {
long tax = generator.nextInt(10) + 15;
tpr.taxPaid(tax);
}
}
if (tpr == null) {
nullCounter++;
}
return tpr;
}
}
package com.fjj.pa.cas;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:35
*/
public interface TaxPayerBailoutDB {
static final int NUMBER_OF_RECORDS_DESIRED = 2*1000000;
TaxPayerRecord get(String id);
TaxPayerRecord add(String id, TaxPayerRecord record);
TaxPayerRecord remove(String id);
int size();
}
package com.fjj.pa.cas;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:37
*/
public class TaxPayerBailoutDbImpl implements TaxPayerBailoutDB {
private final Map<String, TaxPayerRecord> db;
public TaxPayerBailoutDbImpl(int size){
// db = Collections.synchronizedMap(new HashMap<String, TaxPayerRecord>(size));
db = new ConcurrentHashMap<String, TaxPayerRecord>(size);
}
@Override
public TaxPayerRecord get(String id) {
return db.get(id);
}
@Override
public TaxPayerRecord add(String id, TaxPayerRecord record) {
TaxPayerRecord old = db.put(id,record);
if(old!=null){
old = db.put(id,old);
}
return old;
}
@Override
public TaxPayerRecord remove(String id) {
return db.remove(id);
}
@Override
public int size() {
return db.size();
}
}
package com.fjj.pa.cas;
import lombok.Data;
import java.util.concurrent.atomic.AtomicLong;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:31
*/
@Data
public class TaxPayerRecord {
private String firstName,lastName,ssn,address,city,state;
private AtomicLong taxPaid;
public TaxPayerRecord(String firstName,String lastName,String ssn,String address,String city,String state){
this.firstName = firstName;
this.lastName = lastName;
this.ssn = ssn;
this.address = address;
this.city = city;
this.state = state;
this.taxPaid = new AtomicLong(0);
}
public void taxPaid(long amout){
taxPaid.addAndGet(amout);
}
public long getTaxPaid(){
return taxPaid.get();
}
}
package com.fjj.pa.resize;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 14:58
*/
@Data
@AllArgsConstructor
public class BailoutFuture {
private double interationsPerSecond;
private long recordsAdded, recordsRemoced, nullCounter;
}
package com.fjj.pa.resize;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.*;
import java.util.concurrent.*;
public class BailoutMain {
final public static int TEST_TIME = 120 * 1000;
final public static Random random = new Random(Thread.currentThread().getId());
private static char[] alphabet = {'a', 'b', 'c', 'd', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
public static String[] states = {"Alabama", "Alaska", "Arizona",
"Arkansas", "California", "Colorado", "Connecticut",
"Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
"Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky",
"Louisiana", "Maine", "Maryland", "Massachusetts",
"Michigan", "Minnesota", "Mississippi, Missouri", "Montana", "Nebraska",
"Nevada ", "New Hampshire", "New Jersey, New Mexiew York",
"North Carolina", "North Dakota", "Ohioklahoma0regon", "Pennsylvania",
"Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah Vermont", "Virginia", "Washington",
"West Virgina",
"Wisconsin", "Wyoming"};
public static void main(String[] args) {
final int numberOfThreads = Runtime.getRuntime().availableProcessors();
// final int numberOfThreads = 4;
final int dbSize = TaxPayerBailoutDB.NUMBER_OF_RECORDS_DESIRED;
final int taxPayerListSize = dbSize / numberOfThreads;
System.out.println("Number of threads to run concurrently:" + numberOfThreads);
System.out.println("Tax payer database size:" + dbSize);
//
System.out.println("Createing tax payer database...");
TaxPayerBailoutDB db = new TaxPayerBailoutDbImpl(dbSize,states.length);
List<StateAndId>[] taxPayerList = new ArrayList[numberOfThreads];
for (int i = 0; i < numberOfThreads; i++) {
taxPayerList[i] = new ArrayList<StateAndId>(taxPayerListSize);
}
populateDatabase(db, taxPayerList, dbSize);
System.out.println("\tTax payer database created.");
System.out.println("Allocating(" + numberOfThreads + ")threads...");
ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads);
Callable<BailoutFuture>[] callables = new TaxCallable[numberOfThreads];
for (int i = 0; i < callables.length; i++) {
callables[i] = new TaxCallable(taxPayerList[i], db);
}
System.out.println("\tthreads allocated.");
System.out.println("Starting(" + callables.length + ") threads...");
Set<Future<BailoutFuture>> set = new HashSet<Future<BailoutFuture>>();
for (int i = 0; i < callables.length; i++) {
Callable<BailoutFuture> callable = callables[i];
Future<BailoutFuture> future = pool.submit(callable);
set.add(future);
}
System.out.println("\t(" + callables.length + ")threads started.");
System.out.println("Waiting for " + TEST_TIME / 1000 + "seconds for(" + callables.length + ")threads to complete...");
double iterationsPerSecond = 0;
long recordsAdded = 0, recordsRemoved = 0;
long nullCounter = 0;
int counter = 1;
for (Future<BailoutFuture> future : set) {
BailoutFuture result = null;
try {
result = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("Iterations per second on thread[" + counter++ + "]->" + result.getInterationsPerSecond());
iterationsPerSecond += result.getInterationsPerSecond();
recordsAdded += result.getRecordsAdded();
nullCounter = result.getNullCounter();
}
DecimalFormat df = new DecimalFormat("#.##");
System.out.println("Total iterations per second ---------->" + df.format(iterationsPerSecond));
NumberFormat nf = NumberFormat.getInstance();
System.out.println("Total records added ------------------>" + nf.format(recordsAdded));
System.out.println("Total records removed ---------------->" + nf.format(recordsRemoved));
System.out.println("Total records in db ------------------>" + nf.format(db.size()));
System.out.println("Total null records encountered: ------>" + nf.format(nullCounter));
System.exit(0);
}
private static void populateDatabase(TaxPayerBailoutDB db, List<StateAndId>[] taxPayerList, int dbSize) {
for (int i = 0; i < dbSize; i++) {
String key = getRandomTaxPayerId();
TaxPayerRecord tpr = makeTaxPayerRecord();
db.add(key, tpr);
int index = i % taxPayerList.length;
taxPayerList[index].add(new StateAndId(key,tpr.getState()));
}
}
public static String getRandomTaxPayerId() {
StringBuilder sb = new StringBuilder(20);
for (int i = 0; i < 20; i++) {
int index = random.nextInt(alphabet.length);
sb.append(alphabet[index]);
}
return sb.toString();
}
public static TaxPayerRecord makeTaxPayerRecord() {
String firstName = getRandomName();
String laseName = getRandomName();
String ssn = getRandomSSN();
String address = getRandomAddress();
String city = getRandomCity();
String state = getRandomState();
return new TaxPayerRecord(firstName, laseName, ssn, address, city, state);
}
private static String getRandomCity() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(5) + 6;
for (int i = 0; i < size; i++) {
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 0) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
private static String getRandomState() {
int index = random.nextInt(states.length);
return states[index];
}
private static String getRandomAddress() {
StringBuilder sb = new StringBuilder(24);
int size = random.nextInt(14) + 10;
for (int i = 0; i < size; i++) {
if (i < 5) {
int x = random.nextInt(8);
sb.append(x + 1);
}
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 5) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
private static String getRandomSSN() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 11; i++) {
sb.append('-');
}
int x = random.nextInt(9);
sb.append(x);
return sb.toString();
}
private static String getRandomName() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(8) + 5;
for (int i = 0; i < 20; i++) {
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 0) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
}
\ No newline at end of file
package com.fjj.pa.resize;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/23 10:42
*/
@Data
@AllArgsConstructor
public class StateAndId {
String id,state;
}
package com.fjj.pa.resize;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:59
*/
public class TaxCallable implements Callable<BailoutFuture> {
private static long runTimeInMillis = BailoutMain.TEST_TIME;
final private static ThreadLocal<Random> threadLocalRandom = new ThreadLocal<Random>() {
@Override
protected Random initialValue() {
return new Random(Thread.currentThread().getId());
}
};
private long nullCounter, recodesRemoved, newRecordsAdded;
private int index;
private String taxPayerId;
private StateAndId stateAndId;
final private List<StateAndId> taxPayerList;
final private TaxPayerBailoutDB db;
public TaxCallable(List<StateAndId> taxPayerList, TaxPayerBailoutDB db) {
this.taxPayerList = taxPayerList;
this.db = db;
index = 0;
}
@Override
public BailoutFuture call() throws Exception {
long iterations = 0L, elapsedTime = 0L;
long startTime = System.currentTimeMillis();
double iterationsPersecond = 0;
do {
setTaxPayer();
iterations++;
TaxPayerRecord tpr = null;
if (iterations == Long.MAX_VALUE) {
long elapsed = System.currentTimeMillis() - startTime;
iterationsPersecond = iterations / ((double) (elapsed / 1000));
System.err.println("Iteration counter about to overflow ...");
System.err.println("Calculating counter about to second ...");
System.err.println("Iterations per second: " + iterationsPersecond);
iterations = 0L;
startTime = System.currentTimeMillis();
runTimeInMillis -= elapsed;
}
if (iterations % 1001 == 0) {
tpr = addNewTaxPayer(tpr);
} else if (iterations % 60195 == 0) {
tpr = removeTaxPayer(tpr);
} else {
tpr = updateTaxPayer(iterations, tpr);
}
if (iterations % 1000 == 0) {
elapsedTime = System.currentTimeMillis() - startTime;
}
} while (elapsedTime < runTimeInMillis);
if (iterations >= 1000) {
iterationsPersecond = iterations / ((double) (elapsedTime / 1000));
}
BailoutFuture bailoutFuture = new BailoutFuture(iterationsPersecond, newRecordsAdded, recodesRemoved, nullCounter);
return bailoutFuture;
}
private void setTaxPayer() {
if (++index >= taxPayerList.size()) {
index = 0;
}
this.stateAndId = taxPayerList.get(index);
}
private TaxPayerRecord removeTaxPayer(TaxPayerRecord tpr) {
tpr = db.remove(stateAndId.getId(),stateAndId.getState());
if (tpr != null) {
taxPayerList.remove(index);
recodesRemoved++;
}
return tpr;
}
private TaxPayerRecord addNewTaxPayer(TaxPayerRecord tpr) {
String tmpTaxPayerId = BailoutMain.getRandomTaxPayerId();
tpr = BailoutMain.makeTaxPayerRecord();
TaxPayerRecord old = db.add(tmpTaxPayerId, tpr);
if (old == null) {
StateAndId sai = new StateAndId(tmpTaxPayerId,tpr.getState());
taxPayerList.add(sai);
newRecordsAdded++;
}
return tpr;
}
private TaxPayerRecord updateTaxPayer(long iteratios, TaxPayerRecord tpr) {
if (iteratios % 1001 == 0) {
tpr = db.get(stateAndId.getId(),stateAndId.getState());
} else {
tpr = db.get(stateAndId.getId(),stateAndId.getState());
if (tpr != null) {
long tax = threadLocalRandom.get().nextInt(10) + 15;
tpr.taxPaid(tax);
}
}
if (tpr == null) {
nullCounter++;
}
return tpr;
}
}
package com.fjj.pa.resize;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:35
*/
public interface TaxPayerBailoutDB {
static final int NUMBER_OF_RECORDS_DESIRED = 2*1000000;
TaxPayerRecord get(String id, String states);
TaxPayerRecord add(String id, TaxPayerRecord record);
TaxPayerRecord remove(String id, String states);
int size();
}
package com.fjj.pa.resize;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:37
*/
public class TaxPayerBailoutDbImpl implements TaxPayerBailoutDB {
// private final Map<String, TaxPayerRecord> db;
private final Map<String, Map<String, TaxPayerRecord>> db;
public TaxPayerBailoutDbImpl(int size, int states) {
db = new HashMap<String, Map<String, TaxPayerRecord>>();
for (int i = 0; i < states; i++) {
// Map<String, TaxPayerRecord> map = Collections.synchronizedMap(new HashMap<String, TaxPayerRecord>(NUMBER_OF_RECORDS_DESIRED / states));
Map<String, TaxPayerRecord> map = new ConcurrentHashMap<String, TaxPayerRecord>(NUMBER_OF_RECORDS_DESIRED / states);
db.put(BailoutMain.states[i], map);
}
}
@Override
public TaxPayerRecord get(String id, String states) {
Map<String, TaxPayerRecord> record = getStateMap(states);
if (record == null) {
System.out.println("Unable find state:" + states);
}
return record.get(id);
}
@Override
public TaxPayerRecord add(String id, TaxPayerRecord record) {
Map<String, TaxPayerRecord> stateMap = getStateMap(record.getState());
TaxPayerRecord old = stateMap.put(id, record);
if (old != null) {
old = stateMap.put(id, old);
}
return old;
}
@Override
public TaxPayerRecord remove(String id, String states) {
Map<String, TaxPayerRecord> stateMap = getStateMap(states);
TaxPayerRecord tpr = null;
if (stateMap != null) {
tpr = stateMap.remove(id);
}
return tpr;
}
@Override
public int size() {
return db.size();
}
private Map<String, TaxPayerRecord> getStateMap(String states) {
Map<String, TaxPayerRecord> stringTaxPayerRecordMap = db.get(states);
if (stringTaxPayerRecordMap == null) {
throw new UnsupportedOperationException("State:" + states + " not found.");
}
return stringTaxPayerRecordMap;
}
}
package com.fjj.pa.resize;
import lombok.Data;
import java.util.concurrent.atomic.AtomicLong;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:31
*/
@Data
public class TaxPayerRecord {
private String firstName,lastName,ssn,address,city,state;
private AtomicLong taxPaid;
public TaxPayerRecord(String firstName,String lastName,String ssn,String address,String city,String state){
this.firstName = firstName;
this.lastName = lastName;
this.ssn = ssn;
this.address = address;
this.city = city;
this.state = state;
this.taxPaid = new AtomicLong(0);
}
public void taxPaid(long amout){
taxPaid.addAndGet(amout);
}
public long getTaxPaid(){
return taxPaid.get();
}
}
package com.fjj.pa.segment;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 14:58
*/
@Data
@AllArgsConstructor
public class BailoutFuture {
private double interationsPerSecond;
private long recordsAdded, recordsRemoced, nullCounter;
}
package com.fjj.pa.segment;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.*;
import java.util.concurrent.*;
public class BailoutMain {
final public static int TEST_TIME = 120 * 1000;
final public static Random random = new Random(Thread.currentThread().getId());
private static char[] alphabet = {'a', 'b', 'c', 'd', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
public static String[] states = {"Alabama", "Alaska", "Arizona",
"Arkansas", "California", "Colorado", "Connecticut",
"Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
"Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky",
"Louisiana", "Maine", "Maryland", "Massachusetts",
"Michigan", "Minnesota", "Mississippi, Missouri", "Montana", "Nebraska",
"Nevada ", "New Hampshire", "New Jersey, New Mexiew York",
"North Carolina", "North Dakota", "Ohioklahoma0regon", "Pennsylvania",
"Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah Vermont", "Virginia", "Washington",
"West Virgina",
"Wisconsin", "Wyoming"};
public static void main(String[] args) {
final int numberOfThreads = Runtime.getRuntime().availableProcessors();
// final int numberOfThreads = 4;
final int dbSize = TaxPayerBailoutDB.NUMBER_OF_RECORDS_DESIRED;
final int taxPayerListSize = dbSize / numberOfThreads;
System.out.println("Number of threads to run concurrently:" + numberOfThreads);
System.out.println("Tax payer database size:" + dbSize);
//
System.out.println("Createing tax payer database...");
TaxPayerBailoutDB db = new TaxPayerBailoutDbImpl(dbSize,states.length);
List<StateAndId>[] taxPayerList = new ArrayList[numberOfThreads];
for (int i = 0; i < numberOfThreads; i++) {
taxPayerList[i] = new ArrayList<StateAndId>(taxPayerListSize);
}
populateDatabase(db, taxPayerList, dbSize);
System.out.println("\tTax payer database created.");
System.out.println("Allocating(" + numberOfThreads + ")threads...");
ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads);
Callable<BailoutFuture>[] callables = new TaxCallable[numberOfThreads];
for (int i = 0; i < callables.length; i++) {
callables[i] = new TaxCallable(taxPayerList[i], db);
}
System.out.println("\tthreads allocated.");
System.out.println("Starting(" + callables.length + ") threads...");
Set<Future<BailoutFuture>> set = new HashSet<Future<BailoutFuture>>();
for (int i = 0; i < callables.length; i++) {
Callable<BailoutFuture> callable = callables[i];
Future<BailoutFuture> future = pool.submit(callable);
set.add(future);
}
System.out.println("\t(" + callables.length + ")threads started.");
System.out.println("Waiting for " + TEST_TIME / 1000 + "seconds for(" + callables.length + ")threads to complete...");
double iterationsPerSecond = 0;
long recordsAdded = 0, recordsRemoved = 0;
long nullCounter = 0;
int counter = 1;
for (Future<BailoutFuture> future : set) {
BailoutFuture result = null;
try {
result = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("Iterations per second on thread[" + counter++ + "]->" + result.getInterationsPerSecond());
iterationsPerSecond += result.getInterationsPerSecond();
recordsAdded += result.getRecordsAdded();
nullCounter = result.getNullCounter();
}
DecimalFormat df = new DecimalFormat("#.##");
System.out.println("Total iterations per second ---------->" + df.format(iterationsPerSecond));
NumberFormat nf = NumberFormat.getInstance();
System.out.println("Total records added ------------------>" + nf.format(recordsAdded));
System.out.println("Total records removed ---------------->" + nf.format(recordsRemoved));
System.out.println("Total records in db ------------------>" + nf.format(db.size()));
System.out.println("Total null records encountered: ------>" + nf.format(nullCounter));
System.exit(0);
}
private static void populateDatabase(TaxPayerBailoutDB db, List<StateAndId>[] taxPayerList, int dbSize) {
for (int i = 0; i < dbSize; i++) {
String key = getRandomTaxPayerId();
TaxPayerRecord tpr = makeTaxPayerRecord();
db.add(key, tpr);
int index = i % taxPayerList.length;
taxPayerList[index].add(new StateAndId(key,tpr.getState()));
}
}
public static String getRandomTaxPayerId() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 20; i++) {
int index = random.nextInt(alphabet.length);
sb.append(alphabet[index]);
}
return sb.toString();
}
public static TaxPayerRecord makeTaxPayerRecord() {
String firstName = getRandomName();
String laseName = getRandomName();
String ssn = getRandomSSN();
String address = getRandomAddress();
String city = getRandomCity();
String state = getRandomState();
return new TaxPayerRecord(firstName, laseName, ssn, address, city, state);
}
private static String getRandomCity() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(5) + 6;
for (int i = 0; i < size; i++) {
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 0) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
private static String getRandomState() {
int index = random.nextInt(states.length);
return states[index];
}
private static String getRandomAddress() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(14) + 10;
for (int i = 0; i < size; i++) {
if (i < 5) {
int x = random.nextInt(8);
sb.append(x + 1);
}
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 5) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
private static String getRandomSSN() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 11; i++) {
sb.append('-');
}
int x = random.nextInt(9);
sb.append(x);
return sb.toString();
}
private static String getRandomName() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(8) + 5;
for (int i = 0; i < 20; i++) {
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 0) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
}
\ No newline at end of file
package com.fjj.pa.segment;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/23 10:42
*/
@Data
@AllArgsConstructor
public class StateAndId {
String id,state;
}
package com.fjj.pa.segment;
import javax.swing.plaf.nimbus.State;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:59
*/
public class TaxCallable implements Callable<BailoutFuture> {
private static long runTimeInMillis = BailoutMain.TEST_TIME;
final private static ThreadLocal<Random> threadLocalRandom = new ThreadLocal<Random>() {
@Override
protected Random initialValue() {
return new Random(Thread.currentThread().getId());
}
};
private long nullCounter, recodesRemoved, newRecordsAdded;
private int index;
private String taxPayerId;
private StateAndId stateAndId;
final private List<StateAndId> taxPayerList;
final private TaxPayerBailoutDB db;
public TaxCallable(List<StateAndId> taxPayerList, TaxPayerBailoutDB db) {
this.taxPayerList = taxPayerList;
this.db = db;
index = 0;
}
@Override
public BailoutFuture call() throws Exception {
long iterations = 0L, elapsedTime = 0L;
long startTime = System.currentTimeMillis();
double iterationsPersecond = 0;
do {
setTaxPayer();
iterations++;
TaxPayerRecord tpr = null;
if (iterations == Long.MAX_VALUE) {
long elapsed = System.currentTimeMillis() - startTime;
iterationsPersecond = iterations / ((double) (elapsed / 1000));
System.err.println("Iteration counter about to overflow ...");
System.err.println("Calculating counter about to second ...");
System.err.println("Iterations per second: " + iterationsPersecond);
iterations = 0L;
startTime = System.currentTimeMillis();
runTimeInMillis -= elapsed;
}
if (iterations % 1001 == 0) {
tpr = addNewTaxPayer(tpr);
} else if (iterations % 60195 == 0) {
tpr = removeTaxPayer(tpr);
} else {
tpr = updateTaxPayer(iterations, tpr);
}
if (iterations % 1000 == 0) {
elapsedTime = System.currentTimeMillis() - startTime;
}
} while (elapsedTime < runTimeInMillis);
if (iterations >= 1000) {
iterationsPersecond = iterations / ((double) (elapsedTime / 1000));
}
BailoutFuture bailoutFuture = new BailoutFuture(iterationsPersecond, newRecordsAdded, recodesRemoved, nullCounter);
return bailoutFuture;
}
private void setTaxPayer() {
if (++index >= taxPayerList.size()) {
index = 0;
}
this.stateAndId = taxPayerList.get(index);
}
private TaxPayerRecord removeTaxPayer(TaxPayerRecord tpr) {
tpr = db.remove(stateAndId.getId(),stateAndId.getState());
if (tpr != null) {
taxPayerList.remove(index);
recodesRemoved++;
}
return tpr;
}
private TaxPayerRecord addNewTaxPayer(TaxPayerRecord tpr) {
String tmpTaxPayerId = BailoutMain.getRandomTaxPayerId();
tpr = BailoutMain.makeTaxPayerRecord();
TaxPayerRecord old = db.add(tmpTaxPayerId, tpr);
if (old == null) {
StateAndId sai = new StateAndId(tmpTaxPayerId,tpr.getState());
taxPayerList.add(sai);
newRecordsAdded++;
}
return tpr;
}
private TaxPayerRecord updateTaxPayer(long iteratios, TaxPayerRecord tpr) {
if (iteratios % 1001 == 0) {
tpr = db.get(stateAndId.getId(),stateAndId.getState());
} else {
tpr = db.get(stateAndId.getId(),stateAndId.getState());
if (tpr != null) {
long tax = threadLocalRandom.get().nextInt(10) + 15;
tpr.taxPaid(tax);
}
}
if (tpr == null) {
nullCounter++;
}
return tpr;
}
}
package com.fjj.pa.segment;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:35
*/
public interface TaxPayerBailoutDB {
static final int NUMBER_OF_RECORDS_DESIRED = 2*1000000;
TaxPayerRecord get(String id,String states);
TaxPayerRecord add(String id, TaxPayerRecord record);
TaxPayerRecord remove(String id,String states);
int size();
}
package com.fjj.pa.segment;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:37
*/
public class TaxPayerBailoutDbImpl implements TaxPayerBailoutDB {
// private final Map<String, TaxPayerRecord> db;
private final Map<String, Map<String, TaxPayerRecord>> db;
public TaxPayerBailoutDbImpl(int size, int states) {
db = new HashMap<String, Map<String, TaxPayerRecord>>();
for (int i = 0; i < states; i++) {
// Map<String, TaxPayerRecord> map = Collections.synchronizedMap(new HashMap<String, TaxPayerRecord>(NUMBER_OF_RECORDS_DESIRED / states));
Map<String, TaxPayerRecord> map = new ConcurrentHashMap<String, TaxPayerRecord>(NUMBER_OF_RECORDS_DESIRED / states);
db.put(BailoutMain.states[i], map);
}
}
@Override
public TaxPayerRecord get(String id, String states) {
Map<String, TaxPayerRecord> record = getStateMap(states);
if (record == null) {
System.out.println("Unable find state:" + states);
}
return record.get(id);
}
@Override
public TaxPayerRecord add(String id, TaxPayerRecord record) {
Map<String, TaxPayerRecord> stateMap = getStateMap(record.getState());
TaxPayerRecord old = stateMap.put(id, record);
if (old != null) {
old = stateMap.put(id, old);
}
return old;
}
@Override
public TaxPayerRecord remove(String id, String states) {
Map<String, TaxPayerRecord> stateMap = getStateMap(states);
TaxPayerRecord tpr = null;
if (stateMap != null) {
tpr = stateMap.remove(id);
}
return tpr;
}
@Override
public int size() {
return db.size();
}
private Map<String, TaxPayerRecord> getStateMap(String states) {
Map<String, TaxPayerRecord> stringTaxPayerRecordMap = db.get(states);
if (stringTaxPayerRecordMap == null) {
throw new UnsupportedOperationException("State:" + states + " not found.");
}
return stringTaxPayerRecordMap;
}
}
package com.fjj.pa.segment;
import lombok.Data;
import java.util.concurrent.atomic.AtomicLong;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:31
*/
@Data
public class TaxPayerRecord {
private String firstName,lastName,ssn,address,city,state;
private AtomicLong taxPaid;
public TaxPayerRecord(String firstName,String lastName,String ssn,String address,String city,String state){
this.firstName = firstName;
this.lastName = lastName;
this.ssn = ssn;
this.address = address;
this.city = city;
this.state = state;
this.taxPaid = new AtomicLong(0);
}
public void taxPaid(long amout){
taxPaid.addAndGet(amout);
}
public long getTaxPaid(){
return taxPaid.get();
}
}
package com.fjj.pa.threadlocal;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 14:58
*/
@Data
@AllArgsConstructor
public class BailoutFuture {
private double interationsPerSecond;
private long recordsAdded, recordsRemoced, nullCounter;
}
package com.fjj.pa.threadlocal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.*;
import java.util.concurrent.*;
public class BailoutMain {
final public static int TEST_TIME = 120 * 1000;
final public static Random random = new Random(Thread.currentThread().getId());
private static char[] alphabet = {'a', 'b', 'c', 'd', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
private static String[] states = {"Alabama", "Alaska", "Arizona",
"Arkansas", "California", "Colorado", "Connecticut",
"Delaware", "Florida", "Georgia", "Hawaii", "Idaho",
"Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky",
"Louisiana", "Maine", "Maryland", "Massachusetts",
"Michigan", "Minnesota", "Mississippi, Missouri", "Montana", "Nebraska",
"Nevada ", "New Hampshire", "New Jersey, New Mexiew York",
"North Carolina", "North Dakota", "Ohioklahoma0regon", "Pennsylvania",
"Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah Vermont", "Virginia", "Washington",
"West Virgina",
"Wisconsin", "Wyoming"};
public static void main(String[] args) {
final int numberOfThreads = Runtime.getRuntime().availableProcessors();
final int dbSize = TaxPayerBailoutDB.NUMBER_OF_RECORDS_DESIRED;
final int taxPayerListSize = dbSize / numberOfThreads;
System.out.println("Number of threads to run concurrently:" + numberOfThreads);
System.out.println("Tax payer database size:" + dbSize);
//
System.out.println("Createing tax payer database...");
TaxPayerBailoutDB db = new TaxPayerBailoutDbImpl(dbSize);
List<String>[] taxPayerList = new ArrayList[numberOfThreads];
for (int i = 0; i < numberOfThreads; i++) {
taxPayerList[i] = new ArrayList<String>(taxPayerListSize);
}
populateDatabase(db, taxPayerList, dbSize);
System.out.println("\tTax payer database created.");
System.out.println("Allocating(" + numberOfThreads + ")threads...");
ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads);
Callable<BailoutFuture>[] callables = new TaxCallable[numberOfThreads];
for (int i = 0; i < callables.length; i++) {
callables[i] = new TaxCallable(taxPayerList[i], db);
}
System.out.println("\tthreads allocated.");
System.out.println("Starting(" + callables.length + ") threads...");
Set<Future<BailoutFuture>> set = new HashSet<Future<BailoutFuture>>();
for (int i = 0; i < callables.length; i++) {
Callable<BailoutFuture> callable = callables[i];
Future<BailoutFuture> future = pool.submit(callable);
set.add(future);
}
System.out.println("\t(" + callables.length + ")threads started.");
System.out.println("Waiting for " + TEST_TIME / 1000 + "seconds for(" + callables.length + ")threads to complete...");
double iterationsPerSecond = 0;
long recordsAdded = 0, recordsRemoved = 0;
long nullCounter = 0;
int counter = 1;
for (Future<BailoutFuture> future : set) {
BailoutFuture result = null;
try {
result = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("Iterations per second on thread[" + counter++ + "]->" + result.getInterationsPerSecond());
iterationsPerSecond += result.getInterationsPerSecond();
recordsAdded += result.getRecordsAdded();
nullCounter = result.getNullCounter();
}
DecimalFormat df = new DecimalFormat("#.##");
System.out.println("Total iterations per second ---------->" + df.format(iterationsPerSecond));
NumberFormat nf = NumberFormat.getInstance();
System.out.println("Total records added ------------------>" + nf.format(recordsAdded));
System.out.println("Total records removed ---------------->" + nf.format(recordsRemoved));
System.out.println("Total records in db ------------------>" + nf.format(db.size()));
System.out.println("Total null records encountered: ------>" + nf.format(nullCounter));
System.exit(0);
}
private static void populateDatabase(TaxPayerBailoutDB db, List<String>[] taxPayerList, int dbSize) {
for (int i = 0; i < dbSize; i++) {
String key = getRandomTaxPayerId();
TaxPayerRecord tpr = makeTaxPayerRecord();
db.add(key, tpr);
int index = i % taxPayerList.length;
taxPayerList[index].add(key);
}
}
public static String getRandomTaxPayerId() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 20; i++) {
int index = random.nextInt(alphabet.length);
sb.append(alphabet[index]);
}
return sb.toString();
}
public static TaxPayerRecord makeTaxPayerRecord() {
String firstName = getRandomName();
String laseName = getRandomName();
String ssn = getRandomSSN();
String address = getRandomAddress();
String city = getRandomCity();
String state = getRandomState();
return new TaxPayerRecord(firstName, laseName, ssn, address, city, state);
}
private static String getRandomCity() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(5) + 6;
for (int i = 0; i < size; i++) {
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 0) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
private static String getRandomState() {
int index = random.nextInt(states.length);
return states[index];
}
private static String getRandomAddress() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(14) + 10;
for (int i = 0; i < size; i++) {
if (i < 5) {
int x = random.nextInt(8);
sb.append(x + 1);
}
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 5) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
private static String getRandomSSN() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 11; i++) {
sb.append('-');
}
int x = random.nextInt(9);
sb.append(x);
return sb.toString();
}
private static String getRandomName() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(8) + 5;
for (int i = 0; i < 20; i++) {
int index = random.nextInt(alphabet.length);
char c = alphabet[index];
if (i == 0) {
c = Character.toUpperCase(c);
}
sb.append(c);
}
return sb.toString();
}
}
\ No newline at end of file
package com.fjj.pa.threadlocal;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:59
*/
public class TaxCallable implements Callable<BailoutFuture> {
private static long runTimeInMillis = BailoutMain.TEST_TIME;
// final private static Random generator = BailoutMain.random;
final private static ThreadLocal<Random> threadLocalRandom = new ThreadLocal<Random>() {
@Override
protected Random initialValue() {
return new Random(Thread.currentThread().getId());
}
};
private long nullCounter, recodesRemoved, newRecordsAdded;
private int index;
private String taxPayerId;
final private List<String> taxPayerList;
final private TaxPayerBailoutDB db;
public TaxCallable(List<String> taxPayerList, TaxPayerBailoutDB db) {
this.taxPayerList = taxPayerList;
this.db = db;
index = 0;
}
@Override
public BailoutFuture call() throws Exception {
long iterations = 0L, elapsedTime = 0L;
long startTime = System.currentTimeMillis();
double iterationsPersecond = 0;
do {
setTaxPayer();
iterations++;
TaxPayerRecord tpr = null;
if (iterations == Long.MAX_VALUE) {
long elapsed = System.currentTimeMillis() - startTime;
iterationsPersecond = iterations / ((double) (elapsed / 1000));
System.err.println("Iteration counter about to overflow ...");
System.err.println("Calculating counter about to second ...");
System.err.println("Iterations per second: " + iterationsPersecond);
iterations = 0L;
startTime = System.currentTimeMillis();
runTimeInMillis -= elapsed;
}
if (iterations % 1001 == 0) {
tpr = addNewTaxPayer(tpr);
} else if (iterations % 60195 == 0) {
tpr = removeTaxPayer(tpr);
} else {
tpr = updateTaxPayer(iterations, tpr);
}
if (iterations % 1000 == 0) {
elapsedTime = System.currentTimeMillis() - startTime;
}
} while (elapsedTime < runTimeInMillis);
if (iterations >= 1000) {
iterationsPersecond = iterations / ((double) (elapsedTime / 1000));
}
BailoutFuture bailoutFuture = new BailoutFuture(iterationsPersecond, newRecordsAdded, recodesRemoved, nullCounter);
return bailoutFuture;
}
private void setTaxPayer() {
if (++index >= taxPayerList.size()) {
index = 0;
}
this.taxPayerId = taxPayerList.get(index);
}
private TaxPayerRecord removeTaxPayer(TaxPayerRecord tpr) {
tpr = db.remove(taxPayerId);
if (tpr != null) {
taxPayerList.remove(index);
recodesRemoved++;
}
return tpr;
}
private TaxPayerRecord addNewTaxPayer(TaxPayerRecord tpr) {
String tmpTaxPayerId = BailoutMain.getRandomTaxPayerId();
tpr = BailoutMain.makeTaxPayerRecord();
TaxPayerRecord old = db.add(tmpTaxPayerId, tpr);
if (old == null) {
taxPayerList.add(tmpTaxPayerId);
newRecordsAdded++;
}
return tpr;
}
private TaxPayerRecord updateTaxPayer(long iteratios, TaxPayerRecord tpr) {
if (iteratios % 1001 == 0) {
tpr = db.get(taxPayerId);
} else {
tpr = db.get(taxPayerId);
if (tpr != null) {
long tax = threadLocalRandom.get().nextInt(10) + 15;
tpr.taxPaid(tax);
}
}
if (tpr == null) {
nullCounter++;
}
return tpr;
}
}
package com.fjj.pa.threadlocal;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:35
*/
public interface TaxPayerBailoutDB {
static final int NUMBER_OF_RECORDS_DESIRED = 2*1000000;
TaxPayerRecord get(String id);
TaxPayerRecord add(String id, TaxPayerRecord record);
TaxPayerRecord remove(String id);
int size();
}
package com.fjj.pa.threadlocal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:37
*/
public class TaxPayerBailoutDbImpl implements TaxPayerBailoutDB {
private final Map<String, TaxPayerRecord> db;
public TaxPayerBailoutDbImpl(int size){
// db = Collections.synchronizedMap(new HashMap<String, TaxPayerRecord>(size));
db = new ConcurrentHashMap<String, TaxPayerRecord>(size);
}
@Override
public TaxPayerRecord get(String id) {
return db.get(id);
}
@Override
public TaxPayerRecord add(String id, TaxPayerRecord record) {
TaxPayerRecord old = db.put(id,record);
if(old!=null){
old = db.put(id,old);
}
return old;
}
@Override
public TaxPayerRecord remove(String id) {
return db.remove(id);
}
@Override
public int size() {
return db.size();
}
}
package com.fjj.pa.threadlocal;
import lombok.Data;
import java.util.concurrent.atomic.AtomicLong;
/**
* ${description}
*
* @author Fjj
* @date 2020/10/21 16:31
*/
@Data
public class TaxPayerRecord {
private String firstName,lastName,ssn,address,city,state;
private AtomicLong taxPaid;
public TaxPayerRecord(String firstName,String lastName,String ssn,String address,String city,String state){
this.firstName = firstName;
this.lastName = lastName;
this.ssn = ssn;
this.address = address;
this.city = city;
this.state = state;
this.taxPaid = new AtomicLong(0);
}
public void taxPaid(long amout){
taxPaid.addAndGet(amout);
}
public long getTaxPaid(){
return taxPaid.get();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册