Last active
August 29, 2015 13:59
-
-
Save minisu/10858232 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////// There's an infitite loop hidden in this code //////////////////////////// | |
class Foo | |
{ | |
private final HashMap<String, Integer> scores = new HashMap<>(); | |
synchronized resetCount( String name ) | |
{ | |
scores.put( name, 0 ); | |
} | |
synchronized void increaseCount( String name ) | |
{ | |
scores.put( name, scores.get( name ) + 1 ); | |
} | |
int getScore( String name ) | |
{ | |
return scores.get( name ); | |
} | |
} | |
/////////////////////// Consistently synchronized, but still not perfect //////////////////////////// | |
public class Operator { | |
private int generation = 0; //shared variable | |
private float totalAmount = 0; //shared variable | |
private final Object lock = new Object(); | |
public void workOn(List<Operand> operands) { | |
synchronized (lock) { | |
int curGeneration = generation; //requires synch | |
float amountForThisWork = 0; | |
for (Operand o : operands) { | |
o.setGeneration(curGeneration); | |
amountForThisWork += o.amount; | |
} | |
totalAmount += amountForThisWork; //requires synch | |
generation++; //requires synch | |
} | |
} | |
} | |
////////////////////// Consistently synchronized and performant ///////////////////////////// | |
public void workOn(List<Operand> operands) { | |
int curGeneration; | |
float amountForThisWork = 0; | |
synchronized (lock) { | |
int curGeneration = generation++; | |
} | |
for (Operand o : operands) { | |
o.setGeneration(curGeneration); | |
amountForThisWork += o.amount; | |
} | |
synchronized (lock) | |
totalAmount += amountForThisWork; | |
} | |
} | |
//////////////////////// Another example from SoapUI: /////////////////////////// | |
private synchronized void addSamples( SamplesHolder holder ) | |
{ | |
if( adding ) | |
throw new RuntimeException( "Already adding!" ); | |
adding = true; | |
int totalIndex = data.length - 1; | |
if( holder.samples.length != totalIndex || holder.sizes.length != totalIndex ) | |
{ | |
adding = false; | |
throw new RuntimeException( "Unexpected number of samples: " + holder.samples.length + ", exptected " | |
+ ( totalIndex ) ); | |
} | |
// discard "old" results | |
if( holder.startTime < currentThreadCountStartTime ) | |
{ | |
adding = false; | |
return; | |
} | |
// first check that this is not a | |
long timePassed = ( holder.startTime + holder.timeTaken ) - currentThreadCountStartTime; | |
if( resetStatistics ) | |
{ | |
for( int c = 0; c < data.length; c++ ) | |
{ | |
data[c][CURRENT_CNT_COLUMN] = 0; | |
data[c][AVG_COLUMN] = 0; | |
data[c][SUM_COLUMN] = 0; | |
data[c][TPS_COLUMN] = 0; | |
data[c][BYTES_COLUMN] = 0; | |
} | |
totalAverageSum = 0; | |
resetStatistics = false; | |
} | |
long totalMin = 0; | |
long totalMax = 0; | |
long totalBytes = 0; | |
long totalAvg = 0; | |
long totalSum = 0; | |
long totalLast = 0; | |
long threadCount = loadTest.getThreadCount(); | |
for( int c = 0; c < holder.samples.length; c++ ) | |
{ | |
if( holder.sampleCounts[c] > 0 ) | |
{ | |
// only update when appropriate | |
if( holder.complete != loadTest.getUpdateStatisticsPerTestStep() ) | |
{ | |
long sampleAvg = holder.samples[c] / holder.sampleCounts[c]; | |
data[c][LAST_COLUMN] = sampleAvg; | |
data[c][CNT_COLUMN] += holder.sampleCounts[c]; | |
data[c][CURRENT_CNT_COLUMN] += holder.sampleCounts[c]; | |
data[c][SUM_COLUMN] += holder.samples[c]; | |
if( sampleAvg > 0 && ( sampleAvg < data[c][MIN_COLUMN] || data[c][MIN_COLUMN] == 0 ) ) | |
data[c][MIN_COLUMN] = sampleAvg; | |
if( sampleAvg > data[c][MAX_COLUMN] ) | |
data[c][MAX_COLUMN] = sampleAvg; | |
float average = ( float )data[c][SUM_COLUMN] / ( float )data[c][CURRENT_CNT_COLUMN]; | |
data[c][AVG_COLUMN] = ( long )( average * 100 ); | |
data[c][BYTES_COLUMN] += holder.sizes[c]; | |
if( timePassed > 0 ) | |
{ | |
if( loadTest.getCalculateTPSOnTimePassed() ) | |
{ | |
data[c][TPS_COLUMN] = ( data[c][CURRENT_CNT_COLUMN] * 100000 ) / timePassed; | |
data[c][BPS_COLUMN] = ( data[c][BYTES_COLUMN] * 1000 ) / timePassed; | |
} | |
else | |
{ | |
data[c][TPS_COLUMN] = ( long )( data[c][AVG_COLUMN] > 0 ? ( 100000F / average ) * threadCount : 0 ); | |
long avgBytes = data[c][CNT_COLUMN] == 0 ? 0 : data[c][BYTES_COLUMN] / data[c][CNT_COLUMN]; | |
data[c][BPS_COLUMN] = ( avgBytes * data[c][TPS_COLUMN] ) / 100; | |
} | |
} | |
} | |
totalMin += data[c][MIN_COLUMN] * holder.sampleCounts[c]; | |
totalMax += data[c][MAX_COLUMN] * holder.sampleCounts[c]; | |
totalBytes += data[c][BYTES_COLUMN] * holder.sampleCounts[c]; | |
totalAvg += data[c][AVG_COLUMN] * holder.sampleCounts[c]; | |
totalSum += data[c][SUM_COLUMN] * holder.sampleCounts[c]; | |
totalLast += data[c][LAST_COLUMN] * holder.sampleCounts[c]; | |
} | |
else | |
{ | |
totalMin += data[c][MIN_COLUMN]; | |
totalMax += data[c][MAX_COLUMN]; | |
totalBytes += data[c][BYTES_COLUMN]; | |
} | |
} | |
if( holder.complete ) | |
{ | |
data[totalIndex][CNT_COLUMN]++ ; | |
data[totalIndex][CURRENT_CNT_COLUMN]++ ; | |
totalAverageSum += totalLast * 100; | |
data[totalIndex][AVG_COLUMN] = ( long )( ( float )totalAverageSum / ( float )data[totalIndex][CURRENT_CNT_COLUMN] ); | |
data[totalIndex][BYTES_COLUMN] = totalBytes; | |
if( timePassed > 0 ) | |
{ | |
if( loadTest.getCalculateTPSOnTimePassed() ) | |
{ | |
data[totalIndex][TPS_COLUMN] = ( data[totalIndex][CURRENT_CNT_COLUMN] * 100000 ) / timePassed; | |
data[totalIndex][BPS_COLUMN] = ( data[totalIndex][BYTES_COLUMN] * 1000 ) / timePassed; | |
} | |
else | |
{ | |
data[totalIndex][TPS_COLUMN] = ( long )( data[totalIndex][AVG_COLUMN] > 0 ? ( 10000000F / data[totalIndex][AVG_COLUMN] ) | |
* threadCount | |
: 0 ); | |
long avgBytes = data[totalIndex][CNT_COLUMN] == 0 ? 0 : data[totalIndex][BYTES_COLUMN] | |
/ data[totalIndex][CNT_COLUMN]; | |
data[totalIndex][BPS_COLUMN] = ( avgBytes * data[totalIndex][TPS_COLUMN] ) / 100; | |
} | |
} | |
data[totalIndex][MIN_COLUMN] = totalMin; | |
data[totalIndex][MAX_COLUMN] = totalMax; | |
data[totalIndex][SUM_COLUMN] = totalSum; | |
data[totalIndex][LAST_COLUMN] = totalLast; | |
} | |
if( updateFrequency == 0 ) | |
fireTableDataChanged(); | |
else | |
changed = true; | |
adding = false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment