Skip to content

Instantly share code, notes, and snippets.

@yock
Created October 31, 2011 12:57
Show Gist options
  • Save yock/1327440 to your computer and use it in GitHub Desktop.
Save yock/1327440 to your computer and use it in GitHub Desktop.
Threads
package com.cinfin.sharedsvcs.ems.payload;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.*;
/**
* Singleton class for performing compression/decompression operations on
* payload byte arrays.
*
* @author Michael Yockey
*
*/
final class PayloadCompressionUtility {
private static final int DEFLATER_BUFFER_SIZE_INCREMENT = 1024 * 3;
PayloadCompressionUtility() {
}
byte[] compressPayload(byte[] payload) {
Deflater deflater = new Deflater();
deflater.setInput(payload);
deflater.finish();
byte[] buf = new byte[DEFLATER_BUFFER_SIZE_INCREMENT];
int offset = 0;
while (!deflater.finished()) {
deflater.deflate(buf, offset, DEFLATER_BUFFER_SIZE_INCREMENT);
byte[] tmp = buf.clone();
buf = new byte[buf.length + DEFLATER_BUFFER_SIZE_INCREMENT];
System.arraycopy(tmp, 0, buf, 0, tmp.length);
offset += DEFLATER_BUFFER_SIZE_INCREMENT;
}
return buf;
}
byte[] uncompressPayload(byte[] payload, int size)
throws DataFormatException {
byte[] buf = new byte[size];
Inflater inflater = new Inflater();
inflater.setInput(payload);
inflater.inflate(buf);
return buf;
}
String calculateChecksum(byte[] payload) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
synchronized (md) {
byte[] hash = md.digest(payload);
StringBuilder sb = new StringBuilder();
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
} catch (NoSuchAlgorithmException e) {
// This checked exception must be handled to avoid compiler errors.
// This catch block needs no handling code as long as the hashing
// algorithm is dictated by EMS and not by the user.
}
return null;
}
}
@livando
Copy link

livando commented Oct 31, 2011

static PayloadCompressionUtility getInstance() {
if (singletonInstance == null) {
singletonInstance = new PayloadCompressionUtility();
}
return synchronized(singletonInstance);
}

@yock
Copy link
Author

yock commented Oct 31, 2011

No more singleton. Made the constructor package-accessible and synchronized only the operations around MessageDigest.digest(). Most web discussions about synchronizing calls to java.* classes focus on what's written in the Javadoc, ie. never assuming that a class is thread-safe unless it's specified as thread-safe in the Javadoc. I'm going to play with MD a little to see if I can provoke it to behave badly with threads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment