Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小丸子呢
performance analyzer
提交
e4ba6966
P
performance analyzer
项目概览
小丸子呢
/
performance analyzer
通知
2
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
performance analyzer
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
e4ba6966
编写于
10月 26, 2020
作者:
F
feijianjun
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Java性能优化权威指南代码1-线程本地,分段map
上级
b84be146
变更
26
隐藏空白更改
内联
并排
Showing
26 changed file
with
1736 addition
and
0 deletion
+1736
-0
src/main/java/com/fjj/pa/cas/BailoutFuture.java
src/main/java/com/fjj/pa/cas/BailoutFuture.java
+18
-0
src/main/java/com/fjj/pa/cas/BailoutMain.java
src/main/java/com/fjj/pa/cas/BailoutMain.java
+181
-0
src/main/java/com/fjj/pa/cas/TaxCallable.java
src/main/java/com/fjj/pa/cas/TaxCallable.java
+111
-0
src/main/java/com/fjj/pa/cas/TaxPayerBailoutDB.java
src/main/java/com/fjj/pa/cas/TaxPayerBailoutDB.java
+17
-0
src/main/java/com/fjj/pa/cas/TaxPayerBailoutDbImpl.java
src/main/java/com/fjj/pa/cas/TaxPayerBailoutDbImpl.java
+46
-0
src/main/java/com/fjj/pa/cas/TaxPayerRecord.java
src/main/java/com/fjj/pa/cas/TaxPayerRecord.java
+36
-0
src/main/java/com/fjj/pa/resize/BailoutFuture.java
src/main/java/com/fjj/pa/resize/BailoutFuture.java
+18
-0
src/main/java/com/fjj/pa/resize/BailoutMain.java
src/main/java/com/fjj/pa/resize/BailoutMain.java
+182
-0
src/main/java/com/fjj/pa/resize/StateAndId.java
src/main/java/com/fjj/pa/resize/StateAndId.java
+16
-0
src/main/java/com/fjj/pa/resize/TaxCallable.java
src/main/java/com/fjj/pa/resize/TaxCallable.java
+118
-0
src/main/java/com/fjj/pa/resize/TaxPayerBailoutDB.java
src/main/java/com/fjj/pa/resize/TaxPayerBailoutDB.java
+17
-0
src/main/java/com/fjj/pa/resize/TaxPayerBailoutDbImpl.java
src/main/java/com/fjj/pa/resize/TaxPayerBailoutDbImpl.java
+68
-0
src/main/java/com/fjj/pa/resize/TaxPayerRecord.java
src/main/java/com/fjj/pa/resize/TaxPayerRecord.java
+36
-0
src/main/java/com/fjj/pa/segment/BailoutFuture.java
src/main/java/com/fjj/pa/segment/BailoutFuture.java
+18
-0
src/main/java/com/fjj/pa/segment/BailoutMain.java
src/main/java/com/fjj/pa/segment/BailoutMain.java
+182
-0
src/main/java/com/fjj/pa/segment/StateAndId.java
src/main/java/com/fjj/pa/segment/StateAndId.java
+16
-0
src/main/java/com/fjj/pa/segment/TaxCallable.java
src/main/java/com/fjj/pa/segment/TaxCallable.java
+119
-0
src/main/java/com/fjj/pa/segment/TaxPayerBailoutDB.java
src/main/java/com/fjj/pa/segment/TaxPayerBailoutDB.java
+17
-0
src/main/java/com/fjj/pa/segment/TaxPayerBailoutDbImpl.java
src/main/java/com/fjj/pa/segment/TaxPayerBailoutDbImpl.java
+69
-0
src/main/java/com/fjj/pa/segment/TaxPayerRecord.java
src/main/java/com/fjj/pa/segment/TaxPayerRecord.java
+36
-0
src/main/java/com/fjj/pa/threadlocal/BailoutFuture.java
src/main/java/com/fjj/pa/threadlocal/BailoutFuture.java
+18
-0
src/main/java/com/fjj/pa/threadlocal/BailoutMain.java
src/main/java/com/fjj/pa/threadlocal/BailoutMain.java
+181
-0
src/main/java/com/fjj/pa/threadlocal/TaxCallable.java
src/main/java/com/fjj/pa/threadlocal/TaxCallable.java
+117
-0
src/main/java/com/fjj/pa/threadlocal/TaxPayerBailoutDB.java
src/main/java/com/fjj/pa/threadlocal/TaxPayerBailoutDB.java
+17
-0
src/main/java/com/fjj/pa/threadlocal/TaxPayerBailoutDbImpl.java
...in/java/com/fjj/pa/threadlocal/TaxPayerBailoutDbImpl.java
+46
-0
src/main/java/com/fjj/pa/threadlocal/TaxPayerRecord.java
src/main/java/com/fjj/pa/threadlocal/TaxPayerRecord.java
+36
-0
未找到文件。
src/main/java/com/fjj/pa/cas/BailoutFuture.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
src/main/java/com/fjj/pa/cas/BailoutMain.java
0 → 100644
浏览文件 @
e4ba6966
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
src/main/java/com/fjj/pa/cas/TaxCallable.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
}
src/main/java/com/fjj/pa/cas/TaxPayerBailoutDB.java
0 → 100644
浏览文件 @
e4ba6966
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
();
}
src/main/java/com/fjj/pa/cas/TaxPayerBailoutDbImpl.java
0 → 100644
浏览文件 @
e4ba6966
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
();
}
}
src/main/java/com/fjj/pa/cas/TaxPayerRecord.java
0 → 100644
浏览文件 @
e4ba6966
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
();
}
}
src/main/java/com/fjj/pa/resize/BailoutFuture.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
src/main/java/com/fjj/pa/resize/BailoutMain.java
0 → 100644
浏览文件 @
e4ba6966
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
src/main/java/com/fjj/pa/resize/StateAndId.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
src/main/java/com/fjj/pa/resize/TaxCallable.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
}
src/main/java/com/fjj/pa/resize/TaxPayerBailoutDB.java
0 → 100644
浏览文件 @
e4ba6966
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
();
}
src/main/java/com/fjj/pa/resize/TaxPayerBailoutDbImpl.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
}
src/main/java/com/fjj/pa/resize/TaxPayerRecord.java
0 → 100644
浏览文件 @
e4ba6966
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
();
}
}
src/main/java/com/fjj/pa/segment/BailoutFuture.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
src/main/java/com/fjj/pa/segment/BailoutMain.java
0 → 100644
浏览文件 @
e4ba6966
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
src/main/java/com/fjj/pa/segment/StateAndId.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
src/main/java/com/fjj/pa/segment/TaxCallable.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
}
src/main/java/com/fjj/pa/segment/TaxPayerBailoutDB.java
0 → 100644
浏览文件 @
e4ba6966
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
();
}
src/main/java/com/fjj/pa/segment/TaxPayerBailoutDbImpl.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
}
src/main/java/com/fjj/pa/segment/TaxPayerRecord.java
0 → 100644
浏览文件 @
e4ba6966
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
();
}
}
src/main/java/com/fjj/pa/threadlocal/BailoutFuture.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
src/main/java/com/fjj/pa/threadlocal/BailoutMain.java
0 → 100644
浏览文件 @
e4ba6966
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
src/main/java/com/fjj/pa/threadlocal/TaxCallable.java
0 → 100644
浏览文件 @
e4ba6966
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
;
}
}
src/main/java/com/fjj/pa/threadlocal/TaxPayerBailoutDB.java
0 → 100644
浏览文件 @
e4ba6966
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
();
}
src/main/java/com/fjj/pa/threadlocal/TaxPayerBailoutDbImpl.java
0 → 100644
浏览文件 @
e4ba6966
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
();
}
}
src/main/java/com/fjj/pa/threadlocal/TaxPayerRecord.java
0 → 100644
浏览文件 @
e4ba6966
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录