Skip to content

Instantly share code, notes, and snippets.

@minisu
Last active August 29, 2015 13:59
Show Gist options
  • Save minisu/10858232 to your computer and use it in GitHub Desktop.
Save minisu/10858232 to your computer and use it in GitHub Desktop.
/////////////////////// 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